<pre class='metadata'>
Title: Media Queries Level 5
Group: csswg
Shortname: mediaqueries
Level: 5
Status: ED
Work Status: Exploring
ED: https://drafts.csswg.org/mediaqueries-5/
TR: https://www.w3.org/TR/mediaqueries-5/
Previous Version: https://www.w3.org/TR/2021/WD-mediaqueries-5-20211218/
Previous Version: https://www.w3.org/TR/2020/WD-mediaqueries-5-20200731/
Previous Version: https://www.w3.org/TR/2020/WD-mediaqueries-5-20200715/
Previous Version: https://www.w3.org/TR/2020/WD-mediaqueries-5-20200603/
Previous Version: https://www.w3.org/TR/2020/WD-mediaqueries-5-20200318/
Previous Version: https://www.w3.org/TR/2020/WD-mediaqueries-5-20200303/
Editor: Dean Jackson, Apple, w3cid 42080
Editor: Florian Rivoal, Invited Expert, https://florian.rivoal.net, w3cid 43241
Editor: Tab Atkins Jr., Google, http://xanthir.com/contact/, w3cid 42199
Editor: Daniel Libby, Microsoft, w3cid 110974
Editor: Luke Warlow, Igalia, https://lukewarlow.dev, w3cid 142912
Abstract: <a>Media Queries</a> allow authors to test and query values or features of the user agent or display device, independent of the document being rendered.  They are used in the CSS @media rule to conditionally apply styles to a document, and in various other contexts and languages, such as HTML and JavaScript.

	Media Queries Level 5 describes the mechanism and syntax of media queries, media types, and media features. It extends and supersedes the features defined in Media Queries Level 4.
Include MDN Panels: no
At Risk: The '@media/update' media feature
WPT Path Prefix: css/mediaqueries/
WPT Display: open
</pre>

<pre class=link-defaults>
spec:css-conditional-3; type:at-rule; text:@media
spec:css-values-4;
	type:type;
		text:<ratio>
		text:<length>
		text:<integer>
		text:<number>
		text:<resolution>
	type:dfn; text:relative length
spec:dom; type:dfn; text:origin
spec:html;
	type:dfn; for:/; text:browsing context
	type:dfn; for:/; text:joint session history
spec:infra; type:dfn; text:user agent
spec:selectors-4; type:selector;
	text::fullscreen
	text::hover
</pre>

<pre class=biblio>
{
	"ITU-R-BT-2020-2": {
		"href": "https://www.itu.int/rec/R-REC-BT.2020/en",
		"title": "Parameter values for ultra-high definition television systems for production and international programme exchange",
		"date": "October 2015"
	},
	"Display-P3": {
		"title": "Display P3",
		"authors": "Apple, Inc",
		"date": "2022-02",
		"href": "https://www.color.org/chardata/rgb/DisplayP3.xalter"
	}
}
</pre>

<style>
ul.index ul li span {
	white-space: normal;
}
</style>

<h2 id="intro">
Introduction</h2>

	<em>This section is not normative.</em>

	In 1997, HTML4 [[HTML401]] defined a mechanism to support media-dependent style sheets,
	tailored for different <a>media types</a>.
	For example, a document may use different style sheets for screen and for print.
	In HTML, this can be written as:

	<div class="example">
		<pre>
			&lt;link rel="stylesheet" type="text/css" media="screen" href="style.css">
			&lt;link rel="stylesheet" type="text/css" media="print" href="print.css">
		</pre>
	</div>

	CSS adapted and extended this functionality with its ''@media'' and ''@import'' rules,
	adding the ability to query the value of individual features:

	<div class="example">
		Inside a CSS style sheet,
		one can declare that sections apply to certain <a>media types</a>:

		<pre>
			@media screen {
				* { font-family: sans-serif }
			}
		</pre>

		Similarly, stylesheets can be conditionally imported based on media queries:

		<pre>@import "print-styles.css" print;</pre>
	</div>

	<a>Media queries</a> can be used with HTML, XHTML, XML [[xml-stylesheet]] and the @import and @media rules of CSS.

	<div class="example">
		Here is the same example written in HTML, XHTML, XML, @import and @media:

		<pre>
			&lt;link media="screen and (color), projection and (color)"
			      rel="stylesheet" href="example.css">

			&lt;link media="screen and (color), projection and (color)"
			      rel="stylesheet" href="example.css" />

			&lt;?xml-stylesheet media="screen and (color), projection and (color)"
			                 rel="stylesheet" href="example.css" ?>

			@import url(example.css) screen and (color), projection and (color);

			@media screen and (color), projection and (color) { … }
		</pre>

	</div>

<h3 id="placement">
Module interactions</h3>

	This module extends and supersedes [[!MEDIAQUERIES-4]] and its predecessor [[!MEDIAQUERIES-3]],
	which themselves built upon and replaced [[CSS2/media#q7.0]].

<h3 id="values">
Values</h3>

	Value types not defined in this specification, such as <<integer>>,
	<<number>> or <<resolution>>, are defined in [[!CSS-VALUES-4]].  Other CSS
	modules may expand the definitions of these value types.

<h3 id="units">
Units</h3>

	The units used in media queries are the same as in other parts of CSS, as
	defined in [[!CSS-VALUES-4]]. For example, the pixel unit represents CSS pixels and
	not physical pixels.

	[=Relative length=] units in media queries are based on the <a>initial value</a>,
	which means that units are never based on results of declarations.

	Note: For example, in HTML,
	the ''em'' unit is relative to the <a>initial value</a> of 'font-size',
	defined by the user agent or the user's preferences,
	not any styling on the page.
	Note that this will also take into account additional restrictions the user might apply,
	such as minimum font sizes.

	<wpt>
		relative-units-001.html
		relative-units-002.html
		relative-units-003.html
		relative-units-004.html
		relative-units-005.html
	</wpt>

<!--
██     ██  ███████
███   ███ ██     ██
████ ████ ██     ██
██ ███ ██ ██     ██
██     ██ ██  ██ ██
██     ██ ██    ██
██     ██  █████ ██
-->

<h2 id="media">
Media Queries</h2>

	A <dfn export>media query</dfn> is a method of testing certain aspects of the user agent
	or device that the document is being displayed in.
	<a>Media queries</a> are (almost) always independent of the contents of the document,
	its styling,
	or any other internal aspect;
	they're only dependent on “external” information
	unless another feature explicitly specifies that it affects the resolution of Media Queries.

	The syntax of a <a>media query</a> consists of
	an optional <a>media query modifier</a>,
	an optional <a>media type</a>,
	and zero or more <a>media features</a>:

	<pre class='railroad'>
	Or:
		N: media condition
		And:
			Or: 1
				T: only
				S:
				T: not
			N: media type
			Opt:
				And:
					T: and
					N: media condition
	</pre>

	A <a>media query</a> is a logical expression that is either true or false.
	A media query is true if:

	* the <a>media type</a>,
		if specified,
		matches the media type of the device where the user agent is running, and
	* the <a>media condition</a> is true.

	Statements regarding media queries in this section assume the <a href="#mq-syntax">syntax section</a> is followed.
	Media queries that do not conform to the syntax are discussed in [[#error-handling]].
	I.e. the syntax takes precedence over requirements in this section.

	<div class="example">
		Here is a simple example written in HTML:

		<pre>&lt;link rel="stylesheet" media="screen and (color)" href="example.css" /></pre>

		This example expresses that a certain style sheet
		(<code>example.css</code>) applies to devices of a certain media type
		(''screen'') with certain feature (it must be a color screen).

		Here is the same media query written in an @import-rule in CSS:

		<pre>@import url(example.css) screen and (color);</pre>
	</div>

	User agents must re-evaluate <a>media queries</a> in response to changes in the user environment that they're aware of,
	for example if the device is tiled from landscape to portrait orientation,
	and change the behavior of any constructs dependent on those <a>media queries</a> accordingly.

	Unless another feature explicitly specifies that it affects the resolution of Media Queries, it is never necessary to apply a style sheet in order to evaluate expressions.

	<wpt>
		media-queries-001.xht
		media-queries-002.xht
		media-queries-003.xht
		mq-calc-001.html
		mq-calc-002.html
		mq-calc-003.html
		mq-calc-004.html
		mq-calc-005.html
		mq-calc-006.html
		mq-calc-007.html
		mq-calc-008.html
		mq-calc-resolution.html
		mq-calc-sign-function-001.html
		mq-calc-sign-function-002.html
		mq-calc-sign-function-003.html
		mq-calc-sign-function-004.html
		mq-calc-sign-function-005.html
		mq-calc-sign-function-006.html
		mq-dynamic-empty-children.html
		test_media_queries.html
	</wpt>

<h3 id='mq-list'>
Combining Media Queries</h3>

	Several <a>media queries</a> can be combined into a comma-separated <dfn export>media query list</dfn>.

	<pre class='railroad'>
	Star:
		N: media query
		T: ,
	</pre>

	A <a>media query list</a> is true if <em>any</em> of its component <a>media queries</a> are true,
	and false only if <em>all</em> of its component <a>media queries</a> are false.

	<div class="example">
		For example, the following <a>media query list</a> is true if either
		the <a>media type</a> is ''screen'' and it's a color device,
		<strong>or</strong> the <a>media type</a> is ''projection'' and it's a color device:

		<pre>
		@media screen and (color), projection and (color) { … }
		</pre>
	</div>

	An empty <a>media query list</a> evaluates to true.

	<div class="example">
		For example, these are equivalent:

		<pre>
		@media all { … }
		@media { … }
		</pre>
	</div>

<h3 id='mq-prefix'>
Media Query Modifiers</h3>

	A <a>media query</a> may optionally be prefixed by a single <dfn export>media query modifier</dfn>,
	which is a single keyword which alters the meaning of the following <a>media query</a>.

<h4 id='mq-not'>
Negating a Media Query: the ''not'' keyword</h4>

	An individual <a>media query</a> can have its result negated
	by prefixing it with the keyword <dfn value for="@media">not</dfn>.
	If the <a>media query</a> would normally evaluate to true,
	prefixing it with ''not'' makes it evaluate to false,
	and vice versa.

	<div class="example">
		For example, the following will apply to everything except color-capable screens.
		Note that the entire media query is negated,
		not just the <a>media type</a>.

		<pre>&lt;link rel="stylesheet" media="not screen and (color)" href="example.css" /></pre>
	</div>

<h4 id='mq-only'>
Hiding a Media Query From Legacy user agents: the ''only'' keyword</h4>

	The concept of <a>media queries</a> originates from HTML4 [[HTML401]].
	That specification only defined <a>media types</a>,
	but had a forward-compatible syntax that accommodated the addition of future concepts like <a>media features</a>:
	it would consume the characters of a <a>media query</a> up to the first non-alphanumeric character,
	and interpret that as a <a>media type</a>,
	ignoring the rest.
	For example, the <a>media query</a> ''screen and (color)''
	would be truncated to just ''screen''.

	Unfortunately, this means that legacy user agents using this error-handling behavior
	will ignore any <a>media features</a> in a <a>media query</a>,
	even if they're far more important than the <a>media type</a> in the query.
	This can result in styles accidentally being applied in inappropriate situations.

	To hide these <a>media queries</a> from legacy user agents,
	the <a>media query</a> can be prefixed with the keyword <dfn value for="@media">only</dfn>.
	The ''only'' keyword <strong>has no effect</strong> on the <a>media query</a>’s result,
	but will cause the <a>media query</a> to be parsed by legacy user agents
	as specifying the unknown <a>media type</a> “only”,
	and thus be ignored.

	<div class="example">
		In this example, the stylesheet specified by the <code>&lt;link></code> element
		will not be used by legacy user agents,
		even if they would normally match the ''screen'' <a>media type</a>.

		<pre>&lt;link rel="stylesheet" media="only screen and (color)" href="example.css" /></pre>
	</div>

	Note: Note that the ''only'' keyword can only be used before a <a>media type</a>.
	A <a>media query</a> consisting only of <a>media features</a>,
	or one with another <a>media query modifier</a> like ''not'',
	will be treated as false by legacy user agents automatically.

	Note: At the time of publishing this specification,
	such legacy user agents are extremely rare,
	and so using the ''only'' modifier is rarely, if ever, necessary.

<!--
████████ ██    ██ ████████  ████████  ██████
   ██     ██  ██  ██     ██ ██       ██    ██
   ██      ████   ██     ██ ██       ██
   ██       ██    ████████  ██████    ██████
   ██       ██    ██        ██             ██
   ██       ██    ██        ██       ██    ██
   ██       ██    ██        ████████  ██████
-->

<h3 id='media-types'>
Media Types</h3>

	A <dfn export>media type</dfn> is a broad category of user-agent devices
	on which a document may be displayed.
	The original set of <a>media types</a> were defined in HTML4,
	for the <code>media</code> attribute on <code>&lt;link></code> elements.

	Unfortunately, <a>media types</a> have proven insufficient as a way of discriminating between devices with different styling needs.
	Some categories which were originally quite distinct,
	such as ''screen'' and ''handheld'',
	have blended significantly in the years since their invention.
	Others, such as ''tty'' or ''tv'',
	expose useful differences from the norm of a full-featured computer monitor,
	and so are potentially useful to target with different styling,
	but the definition of <a>media types</a> as mutually exclusive
	makes it difficult to use them in a reasonable manner;
	instead, their exclusive aspects are better expressed as <a>media features</a>
	such as '@media/grid' or '@media/scan'.

	As such, the following <a>media types</a> are defined for use in <a>media queries</a>:

	<dl dfn-type=value dfn-for="@media">
		<dt><dfn>all</dfn>
		<dd>Matches all devices.

		<dt><dfn>print</dfn>
		<dd>Matches printers, and devices intended to reproduce a printed display,
			such as a web browser showing a document in “Print Preview”.

		<dt><dfn>screen</dfn>
		<dd>Matches all devices that aren't matched by ''print''.
	</dl>

	In addition, the following <strong>deprecated</strong> <a>media types</a> are defined.
	Authors must not use these <a>media types</a>;
	instead, it is recommended that they select appropriate <a>media features</a>
	that better represent the aspect of the device that they are attempting to style against.

	User agents must recognize the following <a>media types</a> as valid,
	but must make them match nothing.

	<ul dfn-type=value dfn-for="@media">
		<li><dfn>tty</dfn>
		<li><dfn>tv</dfn>
		<li><dfn>projection</dfn>
		<li><dfn>handheld</dfn>
		<li><dfn>braille</dfn>
		<li><dfn>embossed</dfn>
		<li><dfn>aural</dfn>
		<li><dfn>speech</dfn>
	</ul>

	Note: It is expected that all of the media types will also be deprecated in time,
	as appropriate <a>media features</a> are defined which capture their important differences.

	<wpt>
		mq-deprecated-001.html
	</wpt>

<h3 id='mq-features'>
Media Features</h3>

	A <dfn export>media feature</dfn> is a more fine-grained test than <a>media types</a>,
	testing a single, specific feature of the user agent or display device.

	Syntactically, <a>media features</a> resemble CSS properties:
	they consist of a feature name, a colon, and a value to test for.
	They may also be written in boolean form as just a feature name,
	or in range form with a comparison operator.

	<pre class='railroad'>
	T: (
	Choice:
		And:
			N: feature name
			T: :
			N: feature value
		N: feature name
		And:
			N: range form
			C: (see below)
	T: )
	</pre>

	There are, however, several important differences between properties and media features:

	<ul>
		<li>
			Properties are used to give information about how to present a document.
			Media features are used to describe requirements of the output device.

		<li>
			Media features are always wrapped in parentheses
			and combined with the ''and'' or ''or'' keywords,
			like ''(color) and (min-width: 600px)'',
			rather than being separated with semicolons.

		<li>
			A media feature may be given with <em>only</em> its name
			(omitting the colon and value)
			to evaluate the feature in a <a>boolean context</a>.
			This is a convenient shorthand for features that have a reasonable value representing 0 or “none”.
			For example, ''(color)'' is true if the '@media/color' <a>media feature</a> is non-zero.

		<li>
			<a>Media features</a> with “range” type can be written in a <a>range context</a>,
			which uses standard mathematical comparison operators rather than a colon,
			or have their feature names <a href=#mq-min-max>prefixed with “min-” or “max-”</a>.

		<li>
			Properties sometimes accept complex values,
			e.g., calculations that involve several other values.
			<a>Media features</a> only accept single values: one keyword, one number, etc.
	</ul>

	If a <a>media feature</a> references a concept which does not exist on the device where the UA is running
	(for example, speech UAs do not have a concept of “width”),
	the <a>media feature</a> must always evaluate to false.

	<div class="example">
		The media feature '@media/device-aspect-ratio' only applies to
		visual devices. On an ''speech'' device, expressions involving
		'@media/device-aspect-ratio' will therefore always be false:

		<pre>
			&lt;link media="speech and (device-aspect-ratio: 16/9)"
			      rel="stylesheet" href="example.css">
		</pre>
	</div>

<h4 id='mq-ranges'>
Media Feature Types: “range” and “discrete”</h4>

	Every media feature defines its “type” as either “range” or “discrete” in its definition table.

	“Discrete” media features,
	like '@media/pointer'
	take their values from a set.
	The values may be keywords
	or boolean numbers (0 and 1),
	but the common factor is that there's no intrinsic “order” to them--
	none of the values are “less than” or “greater than” each other.

	“Range” media features like '@media/width', on the other hand,
	take their values from a range.
	Any two values can be compared to see which is lesser and which is greater.

	The only significant difference between the two types is that “range” <a>media features</a>
	can be evaluated in a <a>range context</a>
	and accept “min-” and “max-” prefixes on their name.
	Doing either of these changes the meaning of the feature--
	rather than the <a>media feature</a> being true when the feature exactly matches the given value,
	it matches when the feature is greater than/less than/equal to the given value.

	<div class='example'>
		A ''(width >= 600px)'' <a>media feature</a> is true
		when the viewport's width is ''600px'' <em>or more</em>.

		On the other hand, ''(width: 600px)'' by itself is only true
		when the viewport's width is <em>exactly</em> ''600px''.
		If it's less or greater than ''600px'', it'll be false.
	</div>

<!--
████████   ███████   ███████  ██       ████████    ███    ██    ██
██     ██ ██     ██ ██     ██ ██       ██         ██ ██   ███   ██
██     ██ ██     ██ ██     ██ ██       ██        ██   ██  ████  ██
████████  ██     ██ ██     ██ ██       ██████   ██     ██ ██ ██ ██
██     ██ ██     ██ ██     ██ ██       ██       █████████ ██  ████
██     ██ ██     ██ ██     ██ ██       ██       ██     ██ ██   ███
████████   ███████   ███████  ████████ ████████ ██     ██ ██    ██
-->

<h4 id='mq-boolean-context'>
Evaluating Media Features in a Boolean Context</h4>

	While <a>media features</a> normally have a syntax similar to CSS properties,
	they can also be written more simply as just the feature name,
	like ''(color)''.

	When written like this, the <a>media feature</a> is evaluated in a <dfn export>boolean context</dfn>.
	If the feature would be true for any value
	<em>other than</em> the number ''0'',
	a <<dimension>> with the value ''0'',
	the keyword ''@media/update/none'',
	or a value explicitly defined by that media feature to evaluate as false in a boolean context,
	the <a>media feature</a> evaluates to true.
	Otherwise, it evaluates to false.

	<div class='example'>
		Some <a>media features</a> are designed to be written like this.

		For example, '@media/update' is typically written as ''(update)'' to test if any kind of updating is available,
		or ''not (update)'' to check for the opposite.

		It can still be given an explicit value as well,
		with ''(update: fast) or (update: slow)'' equal to ''(update)'',
		and ''(update: none)'' equal to ''not (update)''.
	</div>

	<div class='example'>
		Some numeric <a>media features</a>, like '@media/width',
		are rarely if ever useful to evaluate in a <a>boolean context</a>,
		as their values are almost always greater than zero.
		Others, like '@media/color', have meaningful zero values:
		''(color)'' is identical to ''(color > 0)'',
		indicating that the device is capable of displaying color at all.
	</div>

	<div class='example'>
		Only some of the <a>media features</a> that accept keywords are meaningful in a <a>boolean context</a>.

		For example, ''(pointer)'' is useful,
		as '@media/pointer' has a ''@media/pointer/none'' value to indicate there's no pointing device at all on the device.
		On the other hand, ''(scan)'' is just always true or always false
		(depending on whether it applies at all to the device),
		as there's no value that means “false”.
	</div>

<!--
████████     ███    ██    ██  ██████   ████████
██     ██   ██ ██   ███   ██ ██    ██  ██
██     ██  ██   ██  ████  ██ ██        ██
████████  ██     ██ ██ ██ ██ ██   ████ ██████
██   ██   █████████ ██  ████ ██    ██  ██
██    ██  ██     ██ ██   ███ ██    ██  ██
██     ██ ██     ██ ██    ██  ██████   ████████
-->

<h4 id="mq-range-context">
Evaluating Media Features in a Range Context</h4>


	<a>Media features</a> with a “range” type can be alternately written in a <dfn export>range context</dfn>
	that takes advantage of the fact that their values are ordered,
	using ordinary mathematical comparison operators:

	<pre class='railroad'>
	T: (
	Choice:
		Seq:
			N: feature name/value
			Choice: 4
				T: =
				T: <
				T: <=
				T: >
				T: >=
			N: feature value/name
		Seq:
			N: value
			Choice:
				T: <
				T: <=
			N: feature name
			Choice:
				T: <
				T: <=
			N: value
		Seq:
			N: value
			Choice:
				T: >
				T: >=
			N: feature name
			Choice:
				T: >
				T: >=
			N: value
	T: )
	</pre>

	Note: This syntax is new to Level 4 of Mediaqueries,
	and thus is not as widely supported at the moment
	as the ''min-''/''max-'' prefixes.

	The basic form,
	consisting of a feature name,
	a comparison operator,
	and a value,
	returns true if the relationship is true.

	<div class='example'>
		For example, ''(height > 600px)''
		(or ''(600px &lt; height)'')
		returns true if the viewport height is greater than ''600px''.
	</div>

	The remaining forms,
	with the feature name nested between two value comparisons,
	returns true if both comparisons are true.

	<div class='example'>
		For example, ''(400px &lt; width &lt; 1000px)'' returns true if the viewport width is between ''400px'' and ''1000px''
		(but not equal to either).
	</div>

	Some media features with a "range" type are said to be <dfn>false in the negative range</dfn>.
	This means that negative values are valid and must be parsed, and that
	querying whether the media feature is equal to, less than, or less or equal than
	any such negative value must evaluate to false.
	Querying whether the media feature is greater, or greater or equal, than a negative
	value evaluates to true if the relationship is true.

	Note: If negative values had been rejected at parse time instead,
	they would be treated as ''unknown'' based on the error handling rules.
	However, in reality,
	whether a device's '@media/resolution' is ''-300dpi'' is not unknown, it is known to be false.
	Similarly, for any visual device, the '@media/width' of the targeted display area is known to be greater than ''-200px''
	The above rule reflects that,
	making intuition match what UAs do.

	<div class=example>
	The following examples result in a green background on all visual devices:
<pre><code class=lang-css>
@media not (width <= -100px) {
	body { background: green; }
}
</code></pre>
<pre><code class=lang-css>
@media (height > -100px) {
	body { background: green; }
}
</code></pre>
<pre><code class=lang-css>
@media not (resolution: -300dpi) {
	body { background: green; }
}
</code></pre>
</div>

	<div class=advisement>
	This is a behavior change compared to Media Queries Level 3 [[MEDIAQUERIES-3]],
	where negative values on these properties caused a syntax error.
	In level 3, syntax errors—including forbidden values—resulted in the entire <a>media query</a> being false,
	rather than the ''unknown'' treatment defined in this level.
	Implementations updating from level 3 should make sure
	to change the handling of negative values for the relevant properties
	when they add support for the richer syntax defined in [[#media-conditions]],
	to avoid introducing unintended semantics.
	</div>

	<wpt>
		mq-negative-range-001.html
		mq-negative-range-002.html
	</wpt>

<!--
██     ██ ████ ██    ██       ██ ██     ██    ███    ██     ██
███   ███  ██  ███   ██      ██  ███   ███   ██ ██    ██   ██
████ ████  ██  ████  ██     ██   ████ ████  ██   ██    ██ ██
██ ███ ██  ██  ██ ██ ██    ██    ██ ███ ██ ██     ██    ███
██     ██  ██  ██  ████   ██     ██     ██ █████████   ██ ██
██     ██  ██  ██   ███  ██      ██     ██ ██     ██  ██   ██
██     ██ ████ ██    ██ ██       ██     ██ ██     ██ ██     ██
-->

<h4 id='mq-min-max'>
Using “min-” and “max-” Prefixes On Range Features</h4>

	Rather than evaluating a “range” type <a>media feature</a> in a range context,
	as described above,
	the feature may be written as a normal <a>media feature</a>,
	but with a “min-” or “max-” prefix on the feature name.

	This is equivalent to evaluating the feature in a <a>range context</a>,
	as follows:

	<ul>
		<li>
			Using a “min-” prefix on a feature name is equivalent to using the “>=” operator.
			For example, ''(min-height: 600px)'' is equivalent to ''(height >= 600px)''.

		<li>
			Using a “max-” prefix on a feature name is equivalent to using the “<=” operator.
			For example, ''(max-width: 40em)'' is equivalent to ''(width <= 40em)''.
	</ul>

	Note: because “min-” and “max-” both equate to range comparisons that <strong>include</strong> the value,
	they may be limiting in certain situations.

	<div class='example'>
		For instance,
		authors trying to define different styles based on a breakpoint in the viewport width using “min-” and “max-”
		would generally offset the values they're comparing,
		to ensure that both queries don't evaluate to true simultaneously.
		Assuming the breakpoint is at 320px, authors would conceptually use:

		<pre>
			@media (max-width: 320px) { /* styles for viewports <= 320px */ }
			@media (min-width: 321px) { /* styles for viewports >= 321px */ }
		</pre>

		While this ensures that the two sets of styles don't apply simultaneously when the viewport width is 320px,
		it does not take into account the possibility of fractional viewport sizes which can occur as a result of non-integer pixel densities
		(e.g. on high-dpi displays or as a result of zooming/scaling).
		Any viewport widths that fall between 320px and 321px will result in none of the styles being applied.

		One approach to work around this problem is to increase the precision of the values used for the comparison. Using the example above,
		changing the second comparison value to 320.01px significantly reduces the chance that a viewport width on a device would fall
		between the cracks.

		<pre>
			@media (max-width: 320px) { /* styles for viewports <= 320px */ }
			@media (min-width: 320.01px) { /* styles for viewports >= 320.01px */ }
		</pre>

		However, in these situations, <a>range context</a> queries (which are not limited to “>=” and “<=” comparisons) offer a more appropriate solution:

		<pre>
			@media (width <= 320px) { /* styles for viewports <= 320px */ }
			@media (width > 320px) { /* styles for viewports > 320px */ }
		</pre>
	</div>

	“Discrete” type properties do not accept “min-” or “max-” prefixes.
	Adding such a prefix to a “discrete” type <a>media feature</a> simply results in an unknown feature name.

	<div class='example'>
		For example,
		''(min-grid: 1)'' is invalid,
		because '@media/grid' is a “discrete” <a>media feature</a>,
		and so doesn't accept the prefixes.
		(Even though the '@media/grid' <a>media feature</a> appears to be numeric,
		as it accepts the values ''0'' and ''1''.)
	</div>

	Attempting to evaluate a min/max prefixed <a>media feature</a> in a <a>boolean context</a>
	is invalid and a syntax error.

<h3 id="media-conditions">
Combining Media Features</h3>

	Multiple <a>media features</a> can be combined together into a <dfn export>media condition</dfn>
	using full boolean algebra
	(not, and, or).

	* Any media feature can be negated by placing ''not'' before it.
		For example, ''not (color)'' inverts the meaning of ''(color)''--
		since ''(color)'' matches a device with any kind of color display,
		''not (color)'' matches a device <em>without</em> any kind of color display.

	* Two or more media features can be chained together,
		such that the query is only true if <em>all</em> of the media features are true,
		by placing ''and'' between them.
		For example, ''(width < 600px) and (height < 600px)''
		only matches devices whose screens are smaller than ''600px'' wide in both dimensions.


	* Alternately, two or more media features can be chained together,
		such that the query is true if <em>any</em> of the media features are true,
		by placing ''or'' between them.
		For example, ''(update: slow) or (hover: none)''
		matches if the device is slow to update the screen (such as an e-reader)
		<em>or</em> the primary pointing device has no hover capability,
		perhaps indicating that one should use a layout that displays more information
		rather than compactly hiding it until the user hovers.

	* <a>Media conditions</a> can be grouped by wrapping them in parentheses ''()''
		which can then be nested within a condition the same as a single media query.
		For example, ''(not (color)) or (hover)''
		is true on devices that are monochrome
		and/or that have hover capabilities.
		If one instead wanted to query for a device that was monochrome and <em>didn't</em> have hover capabilities,
		it must instead be written as ''not ((color) or (hover))''
		(or, equivalently, as ''(not (color)) and (not (hover))'').

	It is <em>invalid</em> to mix ''and'' and ''or'' and ''not'' at the same “level” of a media query.
	For example, ''(color) and (pointer) or (hover)'' is illegal,
	as it's unclear what was meant.
	Instead, parentheses can be used to group things using a particular joining keyword,
	yielding either ''(color) and ((pointer) or (hover))''
	or ''((color) and (pointer)) or (hover)''.
	These two have very different meanings:
	if only ''(hover)'' is true,
	the first one evaluates to false
	but the second evaluates to true.

	<wpt>
		negation-001.html
		negation-002.html
	</wpt>

<!--
 ██████  ██    ██ ██    ██ ████████    ███    ██     ██
██    ██  ██  ██  ███   ██    ██      ██ ██    ██   ██
██         ████   ████  ██    ██     ██   ██    ██ ██
 ██████     ██    ██ ██ ██    ██    ██     ██    ███
      ██    ██    ██  ████    ██    █████████   ██ ██
██    ██    ██    ██   ███    ██    ██     ██  ██   ██
 ██████     ██    ██    ██    ██    ██     ██ ██     ██
-->

<h2 id='mq-syntax'>
Syntax</h2>

	Informal descriptions of the media query syntax appear in the prose and railroad diagrams in previous sections.
	The formal media query syntax is described in this section,
	with the rule/property grammar syntax defined in [[!CSS-SYNTAX-3]] and [[!CSS-VALUES-4]].

	To parse a <dfn>&lt;media-query-list></dfn> production,
	<a>parse a comma-separated list of component values</a>,
	then parse each entry in the returned list as a <<media-query>>.
	Its value is the list of <<media-query>>s so produced.

	Note: This explicit definition of <<media-query-list>> parsing
	is necessary to make the error-recovery behavior of <a>media query lists</a> well-defined.

	Note: This definition of <<media-query-list>> parsing intentionally accepts an empty list.

	Note: As per [[!CSS-SYNTAX-3]], tokens are <a>ASCII case-insensitive</a>.

	<pre>
	<dfn>&lt;media-query></dfn> = <<media-condition>>
	             | [ not | only ]? <<media-type>> [ and <<media-condition-without-or>> ]?
	<dfn>&lt;media-type></dfn> = <<ident>>

	<dfn>&lt;media-condition></dfn> = <<media-not>> | <<media-in-parens>> [ <<media-and>>* | <<media-or>>* ]
	<dfn>&lt;media-condition-without-or></dfn> = <<media-not>> | <<media-in-parens>> <<media-and>>*
	<dfn>&lt;media-not></dfn> = not <<media-in-parens>>
	<dfn>&lt;media-and></dfn> = and <<media-in-parens>>
	<dfn>&lt;media-or></dfn> = or <<media-in-parens>>
	<dfn>&lt;media-in-parens></dfn> = ( <<media-condition>> ) | <<media-feature>> | <<general-enclosed>>

	<dfn>&lt;media-feature></dfn> = ( [ <<mf-plain>> | <<mf-boolean>> | <<mf-range>> ] )
	<dfn>&lt;mf-plain></dfn> = <<mf-name>> : <<mf-value>>
	<dfn>&lt;mf-boolean></dfn> = <<mf-name>>
	<dfn>&lt;mf-range></dfn> = <<mf-name>> <<mf-comparison>> <<mf-value>>
	           | <<mf-value>> <<mf-comparison>> <<mf-name>>
	           | <<mf-value>> <<mf-lt>> <<mf-name>> <<mf-lt>> <<mf-value>>
	           | <<mf-value>> <<mf-gt>> <<mf-name>> <<mf-gt>> <<mf-value>>
	<dfn>&lt;mf-name></dfn> = <<ident>>
	<dfn>&lt;mf-value></dfn> = <<number>> | <<dimension>> | <<ident>> | <<ratio>>
	<dfn>&lt;mf-lt></dfn> = '<' '='?
	<dfn>&lt;mf-gt></dfn> = '>' '='?
	<dfn>&lt;mf-eq></dfn> = '='
	<dfn>&lt;mf-comparison></dfn> = <<mf-lt>> | <<mf-gt>> | <<mf-eq>>

	<dfn>&lt;general-enclosed></dfn> = [ <<function-token>> <<any-value>>? ) ] | [ ( <<any-value>>? ) ]
	</pre>

	The <<media-type>> production does not include the keywords ''only'', ''not'', ''and'', ''or'', and ''layer''.

	Note: The exclusion of ''layer'' is because
	it would otherwise be ambiguous
	when when used in the <code highlight=css>@import url(…) layer;</code> syntax
	for the sake of [=cascade layers=].
	See [[CSS-CASCADE-5]].

	No whitespace is allowed between the “<” or “>” <<delim-token>>s and the following “=” <<delim-token>>,
	if it's present.

	Note: Whitespace is required between a ''not'', ''and'', or ''or'' keyword
	and the following ''('' character,
	because without it that would instead parse as a <<function-token>>.
	This is not made explicitly invalid because it's already covered by the above grammar.
	It's fine to have whitespace between a '')'' and a following keyword,
	however.

	When parsing the <<media-in-parens>> production,
	the <<general-enclosed>> branch must only be chosen if the input does not match either of the preceding branches.
	<span class='note'><<general-enclosed>> exists to allow for future expansion of the grammar in a reasonably compatible way.</span>

	<wpt>
		match-media-parsing.html
		mq-case-insensitive-001.html
		mq-range-001.html
		mq-unknown-feature-custom-property.html
	</wpt>

<h3 id=evaluating>
Evaluating Media Queries</h3>

	Each of the major subexpression of <<media-condition>> or <<media-condition-without-or>> is associated with a boolean result, as follows:

	<dl>
		<dt><<media-condition>>
		<dt><<media-condition-without-or>>
		<dd>
			The result is the result of the child subexpression.

		<dt><<media-in-parens>>
		<dd>
			The result is the result of the child term.

		<dt><<media-not>>
		<dd>
			The result is the negation of the <<media-in-parens>> term.
			The negation of unknown is unknown.

		<dt><<media-in-parens>> <<media-and>>*
		<dd>
			The result is true if the <<media-in-parens>> child term
			and all of the <<media-in-parens>> children of the <<media-and>> child terms are true,
			false if at least one of these <<media-in-parens>> terms are false,
			and unknown otherwise.

		<dt><<media-in-parens>> <<media-or>>*
		<dd>
			The result is false if the <<media-in-parens>> child term
			and all of the <<media-in-parens>> children of the <<media-or>> child terms are false,
			true if at least one of these <<media-in-parens>> terms are true,
			and unknown otherwise.

		<dt><<general-enclosed>>
		<dd>
			The result is unknown.

			Authors must not use <<general-enclosed>> in their stylesheets.
			<span class='note'>It exists only for future-compatibility,
			so that new syntax additions do not invalidate too much of a <<media-condition>> in older user agents.</span>

		<dt><<media-feature>>
		<dd>
			The result is the result of evaluating the specified media feature.
	</dl>

	If the result of any of the above productions
	is used in any context that expects a two-valued boolean,
	“unknown” must be converted to “false”.

	Note: This means that,
	for example,
	when a <a>media query</a> is used in a ''@media'' rule,
	if it resolves to “unknown” it's treated as “false”
	and fails to match.

	<div class="note">
		Media Queries use a three-value logic where terms can be “true”, “false”, or “unknown”.
		Specifically, it uses the <a href="http://en.wikipedia.org/wiki/Three-valued_logic#Kleene_and_Priest_logics">Kleene 3-valued logic</a>.
		In this logic, “unknown” means “either true or false, but we're not sure which yet”.

		In general, an unknown value showing up in a formula will cause the formula to be unknown as well,
		as substituting “true” for the unknown will give the formula a different result than substituting “false”.
		The only way to eliminate an unknown value is to use it in a formula that will give the same result
		whether the unknown is replaced with a true or false value.
		This occurs when you have “false AND unknown” (evaluates to false regardless)
		and “true OR unknown” (evaluates to true regardless).

		This logic was adopted because <<general-enclosed>> needs to be assigned a truth value.
		In standard boolean logic, the only reasonable value is “false”,
		but this means that ''not unknown(function)'' is true,
		which can be confusing and unwanted.
		Kleene's 3-valued logic ensures that unknown things will prevent a <a>media query</a> from matching,
		unless their value is irrelevant to the final result.
	</div>


<h3 id="error-handling">
Error Handling</h3>

	A media query that does not match the grammar in the previous section must be replaced by ''not all'' during parsing.

	Note: Note that a grammar mismatch does <strong>not</strong> wipe out an entire <a>media query list</a>,
	just the problematic <a>media query</a>.
	The parsing behavior defined above automatically recovers at the next top-level comma.

	<div class='example'>
		<pre>
			@media (example, all,), speech { /* only applicable to speech devices */ }
			@media &amp;test, speech           { /* only applicable to speech devices */ }
		</pre>

		Both of the above <a>media query lists</a> are turned into ''not all, speech'' during parsing,
		which has the same truth value as just ''speech''.

		Note that error-recovery only happens at the top-level of a <a>media query</a>;
		anything inside of an invalid parenthesized block
		will just get turned into ''not all'' as a group.
		For example:

		<pre>
			@media (example, speech { /* rules for speech devices */ }
		</pre>

		Because the parenthesized block is unclosed,
		it will contain the entire rest of the stylesheet from that point
		(unless it happens to encounter an unmatched “)” character somewhere in the stylesheet),
		and turn the entire thing into a ''not all'' <a>media query</a>.
	</div>

	An unknown <<media-type>> must be treated as not matching.

	<div class='example'>
		For example, the media query ''unknown'' is false,
		as ''unknown'' is an unknown <a>media type</a>.

		But ''not unknown'' is true, as the ''not'' negates the false media type.
	</div>

	<div class='example'>
		Remember that some keywords aren't allowed as <<media-type>>s
		and cause parsing to fail entirely:
		the media query ''or and (color)'' is turned into ''not all'' during parsing,
		rather than just treating the ''or'' as an unknown <a>media type</a>.
	</div>

	An unknown <<mf-name>> or <<mf-value>>, or
	a feature value which does not matches the value syntax for that <a>media feature</a>,
	results in the value “unknown”.
	A <<media-query>> whose value is “unknown” must be replaced with ''not all''.

	<div class="example">
		<pre>&lt;link media="screen and (max-weight: 3kg) and (color), (color)"
		      rel="stylesheet" href="example.css" /&gt;</pre>

		As ''max-weight'' is an unknown <a>media feature</a>,
		this <a>media query list</a> is turned into ''not all, (color)'',
		which is equivalent to just ''(color)''.
	</div>

	<div class="example">
		<pre>@media (min-orientation:portrait) { … }</pre>

		The '@media/orientation' feature does not accept prefixes,
		so this is considered an unknown <a>media feature</a>,
		and turned into ''not all''.
	</div>

	<div class="example">
		The media query ''(color:20example)'' specifies an unknown value for the '@media/color' media feature
		and is therefore turned into ''not all''.
	</div>

	<div class='note'>
		Note that <a>media queries</a> are also subject to the parsing rules of the host language.
		For example, take the following CSS snippet:

		<pre> @media test;,all { body { background:lime } }</pre>

		The media query ''test;,all'' is, parsed by itself,
		equivalent to ''not all, all'', which is always true.
		However, CSS's parsing rules cause the ''@media'' rule,
		and thus the <a>media query</a>,
		to end at the semicolon.
		The remainder of the text is treated as a style rule
		with an invalid selector and contents.
	</div>

	<wpt>
		mq-invalid-media-type-001.html
		mq-invalid-media-type-002.html
		mq-invalid-media-type-003.html
		mq-invalid-media-type-004.html
		mq-invalid-media-type-005.html
		mq-invalid-media-type-006.html
		mq-invalid-media-type-layer-001.html
		mq-invalid-media-type-layer-002.html
	</wpt>

<!--
████████  ████ ██     ██ ████████ ██    ██  ██████  ████  ███████  ██    ██  ██████
██     ██  ██  ███   ███ ██       ███   ██ ██    ██  ██  ██     ██ ███   ██ ██    ██
██     ██  ██  ████ ████ ██       ████  ██ ██        ██  ██     ██ ████  ██ ██
██     ██  ██  ██ ███ ██ ██████   ██ ██ ██  ██████   ██  ██     ██ ██ ██ ██  ██████
██     ██  ██  ██     ██ ██       ██  ████       ██  ██  ██     ██ ██  ████       ██
██     ██  ██  ██     ██ ██       ██   ███ ██    ██  ██  ██     ██ ██   ███ ██    ██
████████  ████ ██     ██ ████████ ██    ██  ██████  ████  ███████  ██    ██  ██████
-->

<h2 id=mf-viewport-characteristics oldids="mf-dimensions">
Viewport/Page Characteristics Media Features</h2>

<h3 id="width">
Width: the '@media/width' feature</h3>

	<pre class='descdef mq'>
	Name: width
	Value: <<length>>
	For: @media
	Type: range
	</pre>

	The '@media/width' media feature describes the width of the targeted display area of the output device.
	For [=continuous media=], this is the width of the viewport
	(as described by CSS2, section 9.1.1 [[!CSS2]])
	including the size of a rendered scroll bar (if any).
	For [=paged media=], this is the width of the page box
	(as described by CSS2, section 13.2 [[!CSS2]]).

	<<length>>s are interpreted according to [[#units]].

	'@media/width' is <a>false in the negative range</a>.

	<div class="example">
		For example, this media query expresses that the style sheet is used on printed output wider than 25cm:

		<pre>&lt;link rel="stylesheet" media="print and (min-width: 25cm)" href="http://…" /></pre>
	</div>

	<div class="example">
		This media query expresses that the style sheet is used on devices with viewport
		(the part of the screen/paper where the document is rendered)
		widths between 400 and 700 pixels:

		<pre>@media (400px <= width <= 700px) { … }</pre>
	</div>

	<div class="example">
		This media query expresses that style sheet is used if the width of the viewport is greater than 20em.

		<pre>@media (min-width: 20em) { … }</pre>

		The ''em'' value is relative to the <a>initial value</a> of 'font-size'.
	</div>

	<wpt>
		media-query-matches-in-iframe.html
		min-width-001.xht
		min-width-tables-001.html
		viewport-script-dynamic.html
	</wpt>


<h3 id="height">
Height: the '@media/height' feature</h3>

	<pre class='descdef mq'>
	Name: height
	Value: <<length>>
	For: @media
	Type: range
	</pre>

	The '@media/height' media feature describes the height of the targeted display area of the output device.
	For [=continuous media=], this is the height of the viewport including the size of a rendered scroll bar (if any).
	For [=paged media=], this is the height of the page box.

	<<length>>s are interpreted according to [[#units]].

	'@media/height' is <a>false in the negative range</a>.

<h3 id='aspect-ratio'>
Aspect-Ratio: the <a descriptor>aspect-ratio</a> feature</h3>

	<pre class='descdef mq'>
	Name: aspect-ratio
	Value: <<ratio>>
	For: @media
	Type: range
	</pre>

	The <a descriptor>aspect-ratio</a> media feature is defined as the ratio of the value of the '@media/width' media feature
	to the value of the '@media/height' media feature.

	<wpt>
		aspect-ratio-006.html
		aspect-ratio-005.html
		aspect-ratio-004.html
		aspect-ratio-003.html
		aspect-ratio-002.html
		aspect-ratio-001.html
		aspect-ratio-serialization.html
	</wpt>

<h3 id='orientation'>
Orientation: the '@media/orientation' feature</h3>

	<pre class='descdef mq'>
	Name: orientation
	Value: portrait | landscape
	For: @media
	Type: discrete
	</pre>

	<dl dfn-type=value dfn-for="@media/orientation">
		<dt><dfn>portrait</dfn>
		<dd>The '@media/orientation' media feature is ''portrait''
		when the value of the '@media/height' media feature is greater than or equal to
		the value of the '@media/width' media feature.
		<dt><dfn>landscape</dfn>
		<dd>Otherwise '@media/orientation' is ''landscape''.
	</dl>

	<div class="example">
		The following media query tests for “portrait” orientation,
		like a phone held upright.

		<pre>@media (orientation:portrait) { … }</pre>
	</div>

<h3 id='mf-overflow-block'>
Block-Axis Overflow: the '@media/overflow-block' feature</h3>

	<pre class='descdef mq'>
	Name: overflow-block
	Value: none | scroll | paged
	For: @media
	Type: discrete
	</pre>

	The '@media/overflow-block' media feature describes the behavior of the device
	when content overflows the initial containing block in the <a status=TR>block axis</a>.

	<dl dfn-type=value dfn-for="@media/overflow-block">
		<dt><dfn>none</dfn>
		<dd>
			There is no affordance for overflow in the <a status=TR>block axis</a>;
			any overflowing content is simply not displayed.
			Examples: billboards

		<dt><dfn>scroll</dfn>
		<dd>
			Overflowing content in the <a status=TR>block axis</a> is exposed by allowing users to scroll to it.
			Examples: computer screens

		<dt><dfn>paged</dfn>
		<dd>
			Content is broken up into discrete pages;
			content that overflows one page in the <a status=TR>block axis</a>
			is displayed on the following page.
			Examples: printers, ebook readers
	</dl>

	Media that match ''overflow-block/none'' or ''overflow-block/scroll'' are said to be <dfn export>continuous media</dfn>,
	while those that match ''overflow-block/paged'' are said to be <dfn export>paged media</dfn>

	Note: Additional values for this media feature may be added in the future
	to describe classes of user agents with a hybrid behavior combining
	aspects of [=continuous media|continuous=] and [=paged media=].
	For example, the Presto layout engine (now discontinued) shipped with
	a semi-paginated presentation-mode behavior similar to ''continuous''
	except that it honored forced page breaks.
	Not knowing of any currently-shipping user agent with this type of behavior,
	the Working Group has decided not to add such a value in this level
	to avoid mischaracterizing any such user agent.
	Anyone implementing a user agent not adequately described
	by any of the values specified above
	is encouraged to contact the Working Group
	so that extensions to this media feature may be considered.

	<wpt>
		overflow-media-features.html
	</wpt>

<h3 id='mf-overflow-inline'>
Inline-Axis Overflow: the '@media/overflow-inline' feature</h3>

	<pre class="descdef mq">
	Name: overflow-inline
	Value: none | scroll
	For: @media
	Type: discrete
	</pre>

	The '@media/overflow-inline' media feature describes the behavior of the device
	when content overflows the initial containing block in the <a status=TR>inline axis</a>.

	<dl dfn-type=value dfn-for="@media/overflow-inline">
		<dt><dfn>none</dfn>
		<dd>
			There is no affordance for overflow in the <a status=TR>inline axis</a>;
			any overflowing content is simply not displayed.

		<dt><dfn>scroll</dfn>
		<dd>
			Overflowing content in the <a status=TR>inline axis</a> is exposed by allowing users to scroll to it.
	</dl>

	Note: There are no known implementations of paged overflow of inline-overflowing content,
	and the very concept doesn't seem to make much sense,
	so there is intentionally no ''paged'' value for '@media/overflow-inline'.

<h3 id='mf-horizontal-viewport-segments'>
Horizontal Viewport Segments: the '@media/horizontal-viewport-segments' feature</h3>

	<pre class="descdef mq">
	Name: horizontal-viewport-segments
	Value: <<integer>>
	For: @media
	Type: range
	</pre>

	The '@media/horizontal-viewport-segments' media feature describes the number of logical segments of
	the viewport in the horizontal direction.

	The '@media/horizontal-viewport-segments' media feature is <a>false in the negative range</a>.

	When the viewport is split by one or more hardware features (such as a fold or a hinge between
	separate displays) that act as a logical divider, segments are the regions of the viewport that
	can be treated as logically distinct by the page.

<h3 id='mf-vertical-viewport-segments'>
Vertical Viewport Segments: the '@media/vertical-viewport-segments' feature</h3>

	<pre class="descdef mq">
	Name: vertical-viewport-segments
	Value: <<integer>>
	For: @media
	Type: range
	</pre>

	The '@media/vertical-viewport-segments' media feature describes the number of logical segments of
	the viewport in the vertical direction.

	The '@media/vertical-viewport-segments' media feature is <a>false in the negative range</a>.

	<div class='example'>
		This media query detects a viewport that has exactly two segments that are side-by-side.

		<pre>@media (horizontal-viewport-segments: 2) and (vertical-viewport-segments: 1) { … }</pre>
	</div>

<h3 id=display-modes>
Display Modes: the '@media/display-mode' media feature</h3>

	<pre class='descdef mq'>
	Name: display-mode
	Value: fullscreen | standalone | minimal-ui | browser | picture-in-picture
	For: @media
	Type: discrete
	</pre>

	The '@media/display-mode' media feature describes the mode in which the current [=browsing context=] is
	currently being presented to the end user.  In child browsing contexts, the [=display mode=] must
	match that of the [=top-level browsing context=].

	This feature is primarily used to determine which [=display mode=] the user agent has applied to
	an [=application context=]. As such, the values of this feature correspond to the [=display
	mode|display modes=] defined in [[APPMANIFEST]]. However, it can also be used in non-application
	contexts to determine whether the viewport is in other modes, such as
	fullscreen or picture-in-picture.


	<dl dfn-type=value dfn-for="@media/display-mode">
		<dt><dfn>fullscreen</dfn>
		<dd>
			The browsing context is displayed with browser UI elements hidden and takes up the entirety of
			the available display area. The fullscreen context may have been caused by the [=display
			mode/fullscreen=] display mode in the [=application manifest=], by the {{requestFullscreen()}}
			method of the [[FULLSCREEN|Fullscreen API]], or through some other means (such as the user
			manually activating fullscreen mode using the user agent's built-in controls).

			Corresponds to the [=display mode/fullscreen=] display mode.

		<dt><dfn>standalone</dfn>
		<dd>
			The [=display mode/standalone=] display mode is in use. Only applicable in an [=application
			context=].

		<dt><dfn>minimal-ui</dfn>
		<dd>
			The [=display mode/minimal-ui=] display mode is in use. Only applicable in an [=application
			context=].

		<dt><dfn>browser</dfn>
		<dd>
			The browsing context is displayed using the platform-specific convention for opening
			hyperlinks in the user agent (e.g., in a browser tab or web browser window with controls such
			as an address bar). This should be used for non-[=application context|application contexts=]
			where no other display mode is appropriate.

			Corresponds to the [=display mode/browser=] display mode.

		<dt><dfn>picture-in-picture</dfn>
		<dd>
			This mode allows users to continue consuming media while they interact
			with other sites or applications on their device.
			The browsing context is displayed in a floating and always-on-top window.
			A user agent may include other platform specific UI elements,
			such as "back-to-tab" and "site information" buttons
			or whatever is customary on the platform and user agent.

	</dl>

	<div class="example">
		For example, the [=application manifest=] can request the [=display mode/standalone=] [=display
		mode=] as follows:
		<pre class="lang-json">
			{
				"display": "standalone"
			}
		</pre>

		This media query can be used to determine whether the user agent has actually applied the
		[=display mode/standalone=] mode:

		<pre class="lang-css">@media (display-mode: standalone) { … }</pre>

		The user agent could set '@media/display-mode' to any of the other values, depending on the
		actual mode currently in use.
	</div>

	<details class="note">
		<summary>The [=display mode/fullscreen=] [=display mode=] is distinct from the
		[[FULLSCREEN|Fullscreen API]].</summary>

		The ''fullscreen'' value for '@media/display-mode' is not directly related
		to the CSS '':fullscreen'' [=pseudo-class=].
		The '':fullscreen'' pseudo-class matches an element
		exclusively when that element is put into the fullscreen element stack.
		However, a side effect of calling the {{requestFullscreen()}} method
		on an element using the [[FULLSCREEN|Fullscreen API]]
		can be that the browser enters a fullscreen mode at the OS-level,
		in which case both '':fullscreen'' and ''(display-mode: fullscreen)'' will match.

		<div class="example">
			On some platforms,
			it is possible for a user--
			or a  [[APPMANIFEST|Web Application Manifest]]--
			to put a web application into fullscreen
			without invoking the [[FULLSCREEN|Fullscreen API]].
			When this happens,
			the '':fullscreen'' pseudo-class will not match,
			but ''(display-mode: fullscreen)'' will match.
			This is exemplified in CSS code below:

			<pre class="lang-css">
				/* applies when the viewport is fullscreen */
				@media (display-mode: fullscreen) { … }

				/* applies when an element is fullscreen */
				#game:fullscreen { … }
			</pre>
		</div>
	</details>

	Note: Additional values for this media feature may be added in the future to
	match new [=display mode|display modes=] added to [[APPMANIFEST]].

	<wpt>
		display-mode.html
	</wpt>

<!--
████████  ████  ██████  ████████         ███████  ██     ██    ███    ██       ████ ████████ ██    ██
██     ██  ██  ██    ██ ██     ██       ██     ██ ██     ██   ██ ██   ██        ██     ██     ██  ██
██     ██  ██  ██       ██     ██       ██     ██ ██     ██  ██   ██  ██        ██     ██      ████
██     ██  ██   ██████  ████████        ██     ██ ██     ██ ██     ██ ██        ██     ██       ██
██     ██  ██        ██ ██              ██  ██ ██ ██     ██ █████████ ██        ██     ██       ██
██     ██  ██  ██    ██ ██              ██    ██  ██     ██ ██     ██ ██        ██     ██       ██
████████  ████  ██████  ██               █████ ██  ███████  ██     ██ ████████ ████    ██       ██
-->

<h2 id='mf-display-quality'>
Display Quality Media Features</h2>

<h3 id="resolution" caniuse="css-media-resolution">
Display Resolution: the '@media/resolution' feature</h3>

	<pre class='descdef mq'>
	Name: resolution
	Value: <<resolution>> | infinite
	For: @media
	Type: range
	</pre>

	The '@media/resolution' media feature describes the resolution of the output
	device, i.e. the density of the pixels, taking into account the <a spec=cssom-view>page zoom</a>
	but assuming a <a spec=cssom-view>pinch zoom</a> of 1.0.

	The '@media/resolution' media feature is <a>false in the negative range</a>

	When querying media with non-square pixels, '@media/resolution' queries the density in the vertical dimension.

	For printers, this corresponds to the screening resolution
	(the resolution for printing dots of arbitrary color).
	Printers might have a different resolution for grayscale printing.

	For output mediums that have no physical constraints on resolution
	(such as outputting to vector graphics),
	this feature must match the <dfn value for="@media/resolution">infinite</dfn> value.
	For the purpose of evaluating this media feature in the <a>range context</a>,
	''infinite'' must be treated as larger than any possible <<resolution>>.
	(That is, a query like ''(resolution > 1000dpi)'' will be true for an ''infinite'' media.)

	<div class='example'>
		This media query simply detects “high-resolution” screens
		(those with a hardware pixel to CSS ''px'' ratio of at least 2):

		<pre>@media (resolution >= 2dppx)</pre>
	</div>

	<div class="example">
		For example, this media query expresses that a style sheet is used on devices with resolution greater than 300 dots per CSS ''in'':

		<pre>@media print and (min-resolution: 300dpi) { … }</pre>

		This media query is equivalent, but uses the CSS ''cm'' unit:

		<pre>@media print and (min-resolution: 118dpcm) { … }</pre>
	</div>

	<div class="note">
		<<resolution>> does not refer to the number of device pixels per physical length unit,
		but the number of device pixels per css unit.
		This mapping is done by the user agent,
		so it is always known to the user agent.

		If the user agent either has no knowledge of the geometry of physical pixels,
		or knows about the geometry physical pixels and they are (close enough to)
		square, it would not map a different number of device pixels per css pixels
		along each axis, and the would therefore be no difference between the vertical
		and horizontal resolution.

		Otherwise, if the UA chooses to map a different number along each axis,
		this would be to respond to physical pixels not being square either. How
		the UA comes to this knowledge is out of scope, but having enough information
		to take this decision, it can invert the mapping should the device be rotated 90 degrees.
	</div>


<h3 id="scan">
Display Type: the '@media/scan' feature</h3>

	<pre class='descdef mq'>
	Name: scan
	Value: interlace | progressive
	For: @media
	Type: discrete
	</pre>

	The '@media/scan' media feature describes the scanning process of some output devices.

	<dl dfn-type=value dfn-for="@media/scan">
		<dt><dfn>interlace</dfn>
		<dd>
			CRT and some types of plasma TV screens used “interlaced” rendering,
			where video frames alternated between specifying only the “even” lines on the screen
			and only the “odd” lines,
			exploiting various automatic mental image-correction abilities to produce smooth motion.
			This allowed them to simulate a higher FPS broadcast at half the bandwidth cost.

			When displaying on interlaced screens,
			authors should avoid very fast movement across the screen to avoid “combing”,
			and should ensure that details on the screen are wider than ''1px'' to avoid <a href="https://en.wikipedia.org/wiki/Interlaced_video#Interline_twitter">“twitter”</a>.

		<dt><dfn>progressive</dfn>
		<dd>
			A screen using “progressive” rendering displays each screen fully,
			and needs no special treatment.

			Most modern screens, and all computer screens, use progressive rendering.
	</dl>

	<div class="example">
		For example, the “feet” of letters in serif fonts are very small features that can provoke “twitter” on interlaced devices.
		The '@media/scan' media feature can be used to detect this,
		and use an alternative font with less chance of “twitter”:

		<pre>@media (scan: interlace) { body { font-family: sans-serif; } }</pre>
	</div>

	Note: At the time of writing, all known implementations match <code>scan: progressive</code> rather than <code>scan: interlace</code>.

<h3 id="grid">
Detecting Console Displays: the '@media/grid' feature</h3>

	<pre class='descdef mq'>
	Name: grid
	Value: <<mq-boolean>>
	For: @media
	Type: discrete
	</pre>

	The '@media/grid' media feature is used to query whether the output device is grid or bitmap.
	If the output device is grid-based
	(e.g., a “tty” terminal, or a phone display with only one fixed font),
	the value will be 1.
	Otherwise, the value will be 0.

	The <dfn type>&lt;mq-boolean></dfn> value type is an <<integer>>
	with the value ''0'' or ''1''.
	Any other integer value is invalid.
	<span class='note'>Note that ''-0'' is always equivalent to ''0'' in CSS,
	and so is also accepted as a valid <<mq-boolean>> value.</span>

	Note: The <<mq-boolean>> type exists only for legacy purposes.
	If this feature were being designed today,
	it would instead use proper named keywords for its values.

	<div class="example">
		Here is an example that detects a narrow console screen:

		<pre>
		@media (grid) and (max-width: 15em) { … }
		</pre>
	</div>

	Note: At the time of writing, all known implementations match <code>grid: 0</code> rather than <code>grid: 1</code>.

<h3 id="update">
Display Update Frequency: the '@media/update' feature</h3>

	<pre class='descdef mq'>
	Name: update
	Value: none | slow | fast
	For: @media
	Type: discrete
	</pre>

	The '@media/update' media feature is used to query the ability of the output device
	to modify the appearance of content once it has been rendered.
	It accepts the following values:

	<dl dfn-type=value dfn-for="@media/update">
		<dt><dfn>none</dfn>
		<dd>
			Once it has been rendered, the layout can no longer be updated.
			Example: documents printed on paper.

		<dt><dfn>slow</dfn>
		<dd>
			The layout may change dynamically according to the usual rules of CSS,
			but the output device is not able to render or display changes quickly enough
			for them to be perceived as a smooth animation.
			Example: E-ink screens or severely under-powered devices.

		<dt><dfn>fast</dfn>
		<dd>
			The layout may change dynamically according to the usual rules of CSS,
			and the output device is not unusually constrained in speed,
			so regularly-updating things like CSS Animations can be used.
			Example: computer screens.
	</dl>

	<div class='example'>
		For example, if a page styles its links to only add underlines on hover,
		it may want to always display underlines when printed:

		<pre>
		@media (update) {
			a { text-decoration: none; }
			a:hover, a:focus { text-decoration: underline; }
		}
		/* In non-updating UAs, the links get their default underline at all times. */
		</pre>
	</div>

	<wpt>
		update-media-feature.html
	</wpt>

<h3 id="environment-blending" oldids="mf-environment">
Detecting the display technology: the '@media/environment-blending' feature</h3>

	<pre class='descdef mq'>
	Name: environment-blending
	Value: opaque | additive | subtractive
	For: @media
	Type: discrete
	</pre>

	The '@media/environment-blending' media feature is used to query the characteristics of the user's display
	so the author can adjust the style of the document.
	An author might choose to adjust the visuals and/or layout of the page depending on the display
	technology to increase the appeal or improve legibility.

	The following values are valid:

	<dl dfn-type=value dfn-for="@media/environment-blending">
		<dt><dfn>opaque</dfn>
		<dd>
			The document is rendered on an opaque medium, such as a traditional monitor or paper.
			Black is dark and white is 100% light.

		<dt><dfn>additive</dfn>
		<dd>
			The display blends the colors of the canvas with the real world using additive mixing.
			Black is fully transparent and white is 100% light.

			For example: a head-up display in a car.

		<dt><dfn>subtractive</dfn>
		<dd>
			The display blends the colors of the canvas with the real world using subtractive mixing.
			White is fully transparent and dark colors have the most contrast.

			For example: an LCD display embedded in a bathroom mirror.
	</dl>

	Issue: Is there a need for the ''subtractive'' value?

	<div class="example">
		<pre>
		body { background-color: white; }
		p { color: black; }

		@media(environment-blending: additive) {
			body { background-color: black; }
			p { color: white; font-size: 16px; font-weight: 1000; }
		}
		</pre>
	</div>

<!--
 ██████   ███████  ██        ███████  ████████
██    ██ ██     ██ ██       ██     ██ ██     ██
██       ██     ██ ██       ██     ██ ██     ██
██       ██     ██ ██       ██     ██ ████████
██       ██     ██ ██       ██     ██ ██   ██
██    ██ ██     ██ ██       ██     ██ ██    ██
 ██████   ███████  ████████  ███████  ██     ██
-->

<h2 id='mf-colors'>
Color Media Features</h2>

<h3 id="color">
Color Depth: the '@media/color' feature</h3>

	<pre class='descdef mq'>
	Name: color
	Value: <<integer>>
	For: @media
	Type: range
	</pre>

	The '@media/color' media feature describes the number of bits per color component of the output device.
	If the device is not a color device, the value is zero.

	'@media/color' is <a>false in the negative range</a>.

	<div class="example">
		For example, these two media queries express that a style sheet applies to all color devices:

		<pre>
		@media (color) { … }
		@media (min-color: 1) { … }
		</pre>
	</div>

	<div class="example">
		This media query expresses that a style sheet applies to color devices
		with at least 8 bits per color component:

		<pre>@media (color >= 8) { … }</pre>
	</div>

	If different color components are represented by different number of bits,
	the smallest number is used.

	<div class="example">
		For instance, if an 8-bit color system
		represents the red component with 3 bits, the green component with 3 bits, and the blue component with 2 bits,
		the '@media/color' media feature will have a value of 2.
	</div>

	In a device with indexed colors,
	the minimum number of bits per color component in the lookup table is used.

	Note: The described functionality is only able to describe color capabilities at a superficial level.
	'@media/color-gamut', is generally more relevant to authors’ needs.
	If further functionality is required,
	RFC2879 [[RFC2879]] provides more specific media features which may be supported at a later stage.

<h3 id="color-index">
Paletted Color Screens: the '@media/color-index' feature</h3>

	<pre class='descdef mq'>
	Name: color-index
	Value: <<integer>>
	For: @media
	Type: range
	</pre>

	The '@media/color-index' media feature describes the number of entries in the color lookup table of the output device.
	If the device does not use a color lookup table, the value is zero.

	'@media/color-index' is <a>false in the negative range</a>.

	<div class="example">
		For example, here are two ways to express that a style sheet applies to all color index devices:

		<pre>
		@media (color-index) { … }
		@media (color-index >= 1) { … }
		</pre>
	</div>


	<div class="example">
		This media query expresses that a style sheet applies to a color index device with 256 or more entries:

		<pre>
		&lt;?xml-stylesheet media="(min-color-index: 256)"
			href="http://www.example.com/…" ?>
		</pre>
	</div>

<h3 id="monochrome">
Monochrome Screens: the '@media/monochrome' feature</h3>

	<pre class='descdef mq'>
	Name: monochrome
	Value: <<integer>>
	For: @media
	Type: range
	</pre>

	The '@media/monochrome' media feature describes the number of bits per pixel in a monochrome frame buffer.
	If the device is not a monochrome device,
	the output device value will be 0.

	'@media/monochrome' is <a>false in the negative range</a>.

	<div class="example">
		For example, this is how to express that a style sheet applies to all monochrome devices:

		<pre>@media (monochrome) { … }</pre>
	</div>

	<div class="example">
		Express that a style sheet applies to monochrome devices with more than 2 bits per pixels:

		<pre>@media (monochrome >= 2) { … }</pre>
	</div>


	<div class="example">
		Express that there is one style sheet for color pages and another for monochrome:

		<pre>
		&lt;link rel="stylesheet" media="print and (color)" href="http://…" />
		&lt;link rel="stylesheet" media="print and (monochrome)" href="http://…" />
		</pre>
	</div>

<h3 id="color-gamut">
Color Display Quality: the '@media/color-gamut' feature</h3>

	<pre class='descdef mq'>
	Name: color-gamut
	Value: srgb | p3 | rec2020
	For: @media
	Type: discrete
	</pre>

	The '@media/color-gamut' media feature describes the approximate range of colors
	that are supported by the UA and output device.
	That is, if the UA receives content with colors in the specified space
	it can cause the output device to render the appropriate color,
	or something appropriately close enough.

	Note: The query uses approximate ranges for a few reasons.
	Firstly, there are a lot of differences in display hardware.
	For example, a device might claim to support "Rec. 2020",
	but actually renders a significantly lower range of the full gamut.
	Secondly, there are a lot of different color ranges that different devices support,
	and enumerating them all would be tedious.
	In most cases the author does not need to know the exact capabilities of the display,
	just whether it is better than sRGB,
	or significantly better than sRGB.
	That way they can serve appropriate images,
	tagged with color profiles,
	to the user.

	<dl dfn-type=value dfn-for="@media/color-gamut">
		<dt><dfn>srgb</dfn>
		<dd>
			The UA and output device can support approximately the sRGB gamut or more.

			Note: It is expected that the vast majority of color displays
			will be able to return true to a query of this type.

		<dt><dfn>p3</dfn>
		<dd>
			The UA and output device can support approximately the gamut
			specified by the Display P3 [[Display-P3]] Color Space or more.

			Note: The ''p3'' gamut is larger than and includes the ''srgb'' gamut.

		<dt><dfn>rec2020</dfn>
		<dd>
			The UA and output device can support approximately the gamut
			specified by the ITU-R Recommendation BT.2020 Color Space or more.

			Note: The ''rec2020'' gamut is larger than and includes the ''p3'' gamut.
	</dl>

	The following table lists the primary colors of these color spaces in terms of their color space chromaticity coordinates,
	as defined in [[!COLORIMETRY]].
	<table class=data>
	<colgroup span="1"></colgroup><colgroup span="2"></colgroup><colgroup span="2"></colgroup><colgroup span="2"></colgroup><colgroup span="2"></colgroup>
	<thead>
	<tr><th rowspan=3>Color Space<th colspan=2 rowspan=2>White Point<th colspan=6>Primaries
	<tr><th colspan=2>Red<th colspan=2>Green<th colspan=2>Blue
	<tr><th>x<sub>W</sub><th>y<sub>W</sub><th>x<sub>R</sub><th>y<sub>R</sub><th>x<sub>G</sub><th>y<sub>G</sub><th>x<sub>B</sub><th>y<sub>B</sub>
	<tbody>
	<tr><td>srgb<td>0.3127<td>0.3290<td>0.640<td>0.330<td>0.300<td>0.600<td>0.150<td>0.060
	<tr><td>p3<td>0.3127<td>0.3290<td>0.680<td>0.320<td>0.265<td>0.690<td>0.150<td>0.060
	<tr><td>rec2020<td>0.3127<td>0.3290<td>0.708<td>0.292<td>0.170<td>0.797<td>0.131<td>0.046

	</table>

	Note: The table above does not contains enough information to fully describe the color spaces,
	but is sufficient to determine whether an output device approximately covers their respective gamuts.
	See [[SRGB]] for more information on sRGB,
	[[Display-P3]] for more information on Display P3,
	and [[ITU-R-BT-2020-2]] for more information on ITU-R Recommendation BT.2020.

	<div class="example">
		For example, this media query applies when the display supports colors
		in the range of Display P3:

		<pre class="lang-css">
		@media (color-gamut: p3) { … }
		</pre>
	</div>

	Note: An output device can return true for multiple values of this media feature,
	if its full output gamut is large enough,
	or one gamut is a subset of another supported gamut.
	As a result,
	this feature is best used in an "ascending" fashion--
	set a base value when ''(color-gamut: srgb)'' is true,
	then override it if ''(color-gamut: p3)'' is true, etc.

	Note: Some output devices,
	such as monochrome displays,
	cannot support even the ''srgb'' gamut.
	To test for these devices,
	you can use this feature in a negated boolean-context fashion:
	''not (color-gamut)''.

	<wpt>
		mq-gamut-001.html
		mq-gamut-002.html
		mq-gamut-003.html
		mq-gamut-004.html
		mq-gamut-005.html
	</wpt>

<h3 id="dynamic-range">
Dynamic Range: the '@media/dynamic-range' feature</h3>

	<pre class='descdef mq'>
	Name: dynamic-range
	Value: standard | high
	For: @media
	Type: discrete
	</pre>

'@media/dynamic-range' represents the combination of max brightness,
color depth, and contrast ratio that are supported by the user agent and output device.

<dl dfn-type=value dfn-for="@media/dynamic-range">
	<dt><dfn>high</dfn>
	<dd>
		The user agent and the output device
		fulfill all of the following criteria:
		* they support a [=high peak brightness=]
		* they support a [=high contrast ratio=]
		* the color depth is greater than 24 bit or 8 bit per color component of RGB

		Note: Some devices have high dynamic range capabilities that are not always on,
		and that need to be activated
		(sometimes programmatically, sometimes by the user, sometimes based on the content).
		This media feature does not test whether such a mode is active,
		just whether the device is capable of high dynamic range visuals.

	<dt><dfn>standard</dfn>
	<dd>
		This value matches on any visual device,
		and not on devices lacking visual capabilities.
</dl>

	Note: More than one value of this media feature can match simultaneously:
	a user agent matching ''dynamic-range/high''
	will also match ''dynamic-range/standard''.

<h4 id="contrast-brightness-of-display">
	Determining contrast and brightness of display</h4>

	<dfn export>Peak brightness</dfn> refers to how bright the brightest point
	a light-emitting device such as an LCD screen can produce,
	or in the case of a light reflective device such as paper or e-ink,
	the point at which it least absorbs light.

	Note: Some devices can only produce their [=peak brightness=]
	for brief periods of time or on a small portion of their surface at any given time.

	The <dfn export>contrast ratio</dfn> is the ratio of the luminance
	of the brightest color to that of the darkest color
	that the system is capable of producing.

	This specification does not define precise ways
	by which these qualities can be measured;
	it also lets the user agent determine
	what counts as a <dfn for="contrast ratio" lt="high contrast ratio">high</dfn> [=contrast ratio=]
	and as a <dfn for="peak brightness" lt="high peak brightness">high</dfn> [=peak brightness=].
	User agents must nonetheless attempt to conform to the following intent:
	a device capable of [=high peak brightness=]
	can display “brighter than white” highlights,
	and a simultaneous ability to do so
	while also presenting deep blacks
	(rather than an overall bright but washed out image)
	is indicative of a [=high contrast ratio=].

	Note: The determination for '@media/dynamic-range' and '@media/video-dynamic-range'
	will be vary depending on the user agent,
	but is expected to have broadly dependable semantics.

	<wpt>
		dynamic-range.html
	</wpt>

<h3 id="inverted">
Detecting inverted colors on the display: the '@media/inverted-colors' feature</h3>

	<pre class='descdef mq'>
	Name: inverted-colors
	Value: none | inverted
	For: @media
	Type: discrete
	</pre>

	The '@media/inverted-colors' media feature indicates whether the content is displayed normally,
	or whether colors have been inverted.

	Note: This is an indication that the user agent or underlying
	operating system has forcibly inverted all colors, not a request to do so.
	This is sometimes provided as a simple accessibility feature,
	allowing users to switch between light-on-dark and dark-on-light text.
	However, this has unpleasant side effects,
	such as inverting pictures,
	or turning shadows into highlights,
	which reduce the readability of the content.

	<dl dfn-type=value dfn-for="@media/inverted-colors">
		<dt><dfn>none</dfn>
		<dd>
			Colors are displayed normally.

		<dt><dfn>inverted</dfn>
		<dd>
			All pixels within the displayed area have been inverted.

			This value must not match
			if the user agent has done some kind of content aware inversion
			such as one that preserves the images.

			Note: This is because the goal of this media feature
			is to enable authors to mitigate the undesirable effects of the non content aware approach
			that invert <em>all</em> the pixels.
			If the author were to take counter measures even in the content-aware cases,
			their counter measures and the UA's would be at risk of cancelling each other.

	</dl>

	<div class="example">
		Depending on their style sheet,
		authors may wish to invert images and videos:

		<pre class="lang-css">
			@media (inverted-colors) {
				img:not(picture > img), picture, video {
					filter: invert(100%);
				}
			}
		</pre>

		Authors may also invert images injected via CSS (such as backgrounds),
		or disable shadows:

		<pre class="lang-css">
		@media (inverted-colors) {
			* {
				text-shadow: none !important;
				box-shadow: none !important;
			}
		}
		</pre>
	</div>

	<wpt>
		inverted-colors.html
	</wpt>

<!--
████ ██    ██ ████████ ████████ ████████     ███     ██████  ████████ ████  ███████  ██    ██
 ██  ███   ██    ██    ██       ██     ██   ██ ██   ██    ██    ██     ██  ██     ██ ███   ██
 ██  ████  ██    ██    ██       ██     ██  ██   ██  ██          ██     ██  ██     ██ ████  ██
 ██  ██ ██ ██    ██    ██████   ████████  ██     ██ ██          ██     ██  ██     ██ ██ ██ ██
 ██  ██  ████    ██    ██       ██   ██   █████████ ██          ██     ██  ██     ██ ██  ████
 ██  ██   ███    ██    ██       ██    ██  ██     ██ ██    ██    ██     ██  ██     ██ ██   ███
████ ██    ██    ██    ████████ ██     ██ ██     ██  ██████     ██    ████  ███████  ██    ██
-->

<h2 id='mf-interaction' caniuse="css-media-interaction">
Interaction Media Features</h2>

	The “interaction” media features reflect various aspects of how the user interacts with the page.

	<div class='note'>
		Typical examples of devices matching combinations of '@media/pointer' and '@media/hover':

		<table class=data>
			<thead>
				<tr>
					<td>
					<th>''pointer: none''
					<th>''pointer: coarse''
					<th>''pointer: fine''
			<tbody>
				<tr>
					<th scope=row>''hover: none''
					<td>keyboard-only controls, sequential/spatial (d-pad) focus navigation
					<td>smartphones, touch screens
					<td>basic stylus digitizers (Cintiq, Wacom, etc)
				<tr>
					<th scope=row>''hover: hover''
					<td>
					<td>Nintendo Wii controller, Kinect
					<td>mouse, touch pad, advanced stylus digitizers (Surface, Samsung Note, Wacom Intuos Pro, etc)
		</table>
		<style>
			#pointer-hover-table { margin: 1em auto; text-align: center; border-collapse: collapse; max-width: 40em; }
			#pointer-hover-table td, #pointer-hover-table th { padding: .5em; }
			#pointer-hover-table thead tr+tr th { border-bottom: 1px solid silver; }
			#pointer-hover-table tbody td:first-of-type { border-left: 1px solid silver; }
		</style>
	</div>

	The '@media/pointer' and '@media/hover' features relate to the characteristics of the “primary” pointing device,
	while '@media/any-pointer' and '@media/any-hover' can be used to query the properties of all potentially available pointing devices.

	Note: While this specification does not define how user agents should decide what the “primary” pointing device is,
	the expectation is that user agents should make this determination
	by combining knowledge about the device/environment they are running on,
	the number and type of pointing devices available,
	and a notion of which of these is generally and/or currently being used.
	In situations where the primary input mechanism for a device is not a pointing device,
	but there is a secondary – and less frequently used – input that is a pointing devices,
	the user agent may decide to treat the non-pointing device as the primary (resulting in 'pointer: none').
	user agents may also decide to dynamically change what type of pointing device is deemed to be primary,
	in response to changes in the user environment
	or in the way the user is interacting with the UA.

	Note: The '@media/pointer', '@media/hover', '@media/any-pointer' and '@media/any-hover' features only relate to the characteristics,
	or the complete absence, of pointing devices,
	and can not be used to detect the presence of non-pointing device input mechanisms such as keyboards.
	Authors should take into account the potential presence of non-pointing device inputs,
	regardless of which values are matched when querying these features.

	<div class="note">
		While '@media/pointer' and '@media/hover' can be used to design the main style and interaction
		mode of the page to suit the primary input mechanism (based on the characteristics, or complete absence,
		of the primary pointing device), authors should strongly consider using '@media/any-pointer' and '@media/any-hover'
		to take into account all possible types of pointing devices	that have been detected.
	</div>

<h3 id="pointer">
Pointing Device Quality: the '@media/pointer' feature</h3>

	<pre class='descdef mq'>
	Name: pointer
	Value: none | coarse | fine
	For: @media
	Type: discrete
	</pre>

	The '@media/pointer' media feature is used to query the presence and accuracy of a pointing device such as a mouse.
	If multiple pointing devices are present,
	the '@media/pointer' media feature must reflect the characteristics of the “primary” pointing device,
	as determined by the user agent.
	(To query the capabilities of <em>any</em> available pointing devices,
		see the '@media/any-pointer' media feature.)

	<dl dfn-type=value dfn-for="@media/pointer">
		<dt><dfn>none</dfn>
		<dd>The primary input mechanism of the device does not include a pointing device.

		<dt><dfn>coarse</dfn>
		<dd>The primary input mechanism of the device includes a pointing device of limited accuracy.
			Examples include touchscreens and motion-detection sensors (like the Kinect peripheral for the Xbox.)

		<dt><dfn>fine</dfn>
		<dd>The primary input mechanism of the device includes an accurate pointing device.
			Examples include mice, touchpads, and drawing styluses.
	</dl>

	Both ''coarse'' and ''fine'' indicate the presence of a pointing device,
	but differ in accuracy.
	A pointing device with which it would be difficult or impossible
	to reliably pick one of several small adjacent targets at a zoom factor of 1
	would qualify as ''coarse''.
	Changing the zoom level does not affect the value of this media feature.

	Note: As the UA may provide the user with the ability to zoom,
	or as secondary pointing devices may have a different accuracy,
	the user may be able to perform accurate clicks even if the value of this media feature is ''coarse''.
	This media feature does not indicate that the user will never be able to click accurately,
	only that it is inconvenient for them to do so.
	Authors are expected to react to a value of ''coarse''
	by designing pages that do not rely on accurate clicking to be operated.

	For accessibility reasons,
	even on devices whose pointing device can be described as ''fine'',
	the UA may give a value of ''coarse'' or ''pointer/none'' to this media query,
	to indicate that the user has difficulties manipulating the pointing device accurately or at all.
	In addition, even if the primary pointing device has ''fine'' pointing accuracy,
	there may be additional ''coarse'' pointing devices available to the user. Authors may
	wish to query the '@media/any-pointer' media feature to take these other ''coarse'' potential
	pointing devices into account.

	<div class="example">
		<pre>
		/* Make radio buttons and check boxes larger if we have an inaccurate primary pointing device */
		@media (pointer:coarse) {
			input[type="checkbox"], input[type="radio"] {
				min-width:30px;
				min-height:40px;
				background:transparent;
			}
		}
		</pre>
	</div>

<h3 id="hover">
Hover Capability: the '@media/hover' feature</h3>

	<pre class='descdef mq'>
	Name: hover
	Value: none | hover
	For: @media
	Type: discrete
	</pre>

	The '@media/hover' media feature is used to query the user's ability to hover over elements on the page
	with the primary pointing device.
	If a device has multiple pointing devices,
	the '@media/hover' media feature must reflect the characteristics of the “primary” pointing device,
	as determined by the user agent.
	(To query the capabilities of <em>any</em> available pointing devices,
		see the '@media/any-hover' media feature.)

	<dl dfn-type=value dfn-for="@media/hover">
		<dt><dfn>none</dfn>
		<dd>
			Indicates that the primary pointing device can't hover,
			or that there is no pointing device.
			Examples include touchscreens and screens that use a basic drawing stylus.

			Pointing devices that can hover,
			but for which doing so is inconvenient and not part of the normal way they are used,
			also match this value.
			For example, a touchscreen where a long press is treated as hovering
			would match ''hover: none''.

		<dt><dfn>hover</dfn>
		<dd>
			Indicates that the primary pointing device can easily hover over parts of the page.
			Examples include mice and devices that physically point at the screen, like the Nintendo Wii controller.
	</dl>

	<div class='example'>
		For example, on a touch screen device that can also be controlled by an optional mouse,
		the '@media/hover' <a>media feature</a> should match ''hover: none'',
		as the primary pointing device (the touch screen) does not allow the user to hover.

		However, despite this, the optional mouse does allow users to hover.
		Authors should therefore be careful not to assume that the '':hover'' [=pseudo-class=]
		will never match on a device where 'hover:none' is true,
		but they should design layouts that do not depend on hovering to be fully usable.
	</div>

	For accessibility reasons, even on devices that do support hovering,
	the UA may give a value of ''hover: none'' to this media query,
	to opt into layouts that work well without hovering.
	Note that even if the primary input mechanism has 'hover: hover' capability,
	there may be additional input mechanisms available to the user that do not provide hover capabilities.

	<div class="example">
		<pre>
		/* Only use a hover-activated drop down menu on devices that can conveniently hover. */
		@media (hover) {
			.menu > li        {display:inline-block;}
			.menu ul          {display:none; position:absolute;}
			.menu li:hover ul {display:block; list-style:none; padding:0;}
			/* ... */
		}
		</pre>
	</div>

<h3 id='any-input'>
All Available Interaction Capabilities: the '@media/any-pointer' and '@media/any-hover' features</h3>

	<pre class='descdef mq'>
	Name: any-pointer
	Value: none | coarse | fine
	For: @media
	Type: discrete
	</pre>

	<pre class='descdef mq'>
	Name: any-hover
	Value: none | hover
	For: @media
	Type: discrete
	</pre>

	The '@media/any-pointer' and '@media/any-hover' media features are identical to the '@media/pointer' and '@media/hover' media features,
	but they correspond to the union of capabilities of all the pointing devices available to the user.
	In the case of '@media/any-pointer', more than one of the values can match,
	if different pointing devices have different characteristics.

	'@media/any-pointer' and '@media/any-hover' must only match ''@media/any-pointer/none'' if <em>all</em> of the pointing devices would match ''@media/pointer/none'' for the corresponding query,
	or there are no pointing devices at all.

	<div class="note">
	'@media/any-pointer' is used to query the presence and accuracy of pointing devices.
	It does not take into account any additional non-pointing device inputs,
	and can not be used to test for the presence of other input mechanisms,
	such as d-pads or keyboard-only controls,
	that don't move an on-screen pointer.
	'any-pointer:none' will only evaluate to true if there are no pointing devices at all present.
	</div>

	<div class="example">
	On a traditional desktop environment with a mouse and keyboard,
	'any-pointer:none' will be false (due to the presence of the mouse),
	even though a non-pointer input (the keyboard) is also present.
	</div>

	<div class="note">
	'any-hover:none' will only evaluate to true if there are no pointing devices,
	or if all the pointing devices present lack hover capabilities.
	As such, it should be understood as a query to test if any hover-capable pointing devices are present,
	rather than whether or not any of the pointing devices is hover-incapable.
	The latter scenario can currently not be determined using '@media/any-hover' or any other interaction media feature.
	Additionally, it does not take into account any non-pointing device inputs,
	such as d-pads or keyboard-only controls,
	which by their very nature are also not hover-capable.
	</div>

	<div class="example">
	On a touch-enabled laptop with a mouse and a touchscreen,
	'any-hover:none' will evaluate to false (due to the presence of the hover-capable mouse),
	even though a non-hover-capable pointing device (the touchscreen) is also present.
	It is currently not possible to provide different styles for cases where different pointing devices have different hover capabilities.
	</div>

	<div class="note">
	Designing a page that relies on hovering or accurate pointing
	only because '@media/any-hover' or '@media/any-pointer' indicate that at least one of the available
	input mechanisms has these capabilities	is likely to result in a poor experience.
	However, authors may use this information to inform their decision about the style and
	functionality they wish to provide based on any additional pointing devices that
	are available to the user.
	</div>

	<div class="example">
		A number of smart TVs come with a way to control an on-screen cursor,
		but it is often fairly basic controller which is difficult to operate accurately.

		A browser in such a smart TV would have ''coarse'' as the value of both '@media/pointer' and '@media/any-pointer',
		allowing authors to provide a layout with large and easy to reach click targets.

		The user may also have paired a Bluetooth mouse with the TV,
		and occasionally use it for extra convenience,
		but this mouse is not the main way the TV is operated.
		'@media/pointer' still matches ''coarse'', while '@media/any-pointer' now both matches ''coarse'' and ''fine''.

		Switching to small click targets based on the fact that ''(any-pointer: fine)'' is now true
		would not be appropriate.
		It would not only surprise the user
		by providing an experience out of line with what they expect on a TV,
		but may also be quite inconvenient:
		the mouse, not being the primary way to control the TV, may be out of reach,
		hidden under one of the cushions on the sofa...

		By contrast, consider scrolling on the same TV.
		Scrollbars are difficult to manipulate without an accurate pointing device.
		Having prepared an alternative way to indicate that there is more content to be seen
		based on ''(pointer: coarse)'' being true,
		an author may want to still show the scrollbars in addition if ''(any-pointer: fine)'' is true,
		or to hide them altogether to reduce visual clutter if ''(any-pointer: fine)'' is false.
	</div>

<h3 id=nav-controls>
Detecting UA-supplied navigation controls: the '@media/nav-controls' feature</h3>

	<pre class='descdef mq'>
	Name: nav-controls
	Value: none | back
	For: @media
	Type: discrete
	</pre>

	The '@media/nav-controls' media features allows authors to know
	whether the user agent is providing [=obviously discoverable=] navigation controls
	as part of its user interface.

	Note: Traditional browsers typically do provide such controls
	and web pages typically have not needed to concern themselves with that,
	but in some contexts,
	web applications are run through so-called web-views,
	which do not always feature a full-fledged user interface.
	It is thus useful for authors to know
	what is being supplied by the user agent,
	so that they can consider
	whether they need to provide an easily discovered alternative.

	In this context, <dfn>obviously discoverable</dfn> refers to controls
	which are either directly visible in the user interface,
	such as buttons,
	or some other form of control which is typical of the user interface of that device
	and trivially identifiable by the user.
	In the case of visual user interfaces,
	this would typically a <em>visible</em> control,
	although it could be something else in the case of an audio or tactile user interface.
	Importantly,
	this is not about keyboard shortcuts or gestures;
	as convenient as these can be,
	these are not obviously discoverable by just looking at (in the case of a visual UI) the user agent.

	The following values are valid:

	<dl dfn-type=value dfn-for="@media/nav-controls">
		<dt><dfn>none</dfn>
		<dd>
			The user agent does not have any [=obviously discoverable=] navigation controls,
			and in particular none that cause the user agent
			to move back one page in the [=joint session history=].

		<dt><dfn>back</dfn>
		<dd>
			The user agent provides navigation controls,
			including at least an [=obviously discoverable=] control
			causing the user agent to move back one page in the [=joint session history=]
			(typically, a “back” button).
	</dl>

	<div class=example>
		Authors can include a back button in their web application,
		and then conditionally hide it
		if the user agent already offers that functionality:

		<pre><code class=lang-css>
		@media (nav-controls: back) {
			#back-button {
				display: none;
			}
		}</code></pre>

		As this media feature can be used in a [=boolean context=],
		the same example can be written with shorter syntax:

		<pre><code class=lang-css>
		@media (nav-controls) {
			#back-button {
				display: none;
			}
		}</code></pre>

		Note: Theoretically, the two are not strictly equivalent,
		as there could be new values in a future extension of this media feature
		other than ''back''
		that could match when ''back'' doesn't.
		In that case, using the '@media/nav-controls' feature in a boolean context could be misleading.
		However, given that navigation back is arguably the most fundamental navigation operation,
		the CSS Working Group does not anticipate
		user interfaces with explicit navigation controls but no back button,
		so this problem is not expected to occur in practice.
	</div>

	Whether [=obviously discoverable=] controls are active does not impact the evaluation of this media feature.

	<div class=example>
		If there is no previous page in the [=joint session history=],
		a user agent with a “back” button could toggle it to a disabled state
		that cannot be interacted with until there actually is history
		that can be navigated back to.
		In such a case,
		<code class=lang=css>@media (nav-controls: back) { … }</code>
		would still be expected to match.
	</div>


<!--
██     ██ ████ ████████  ████████  ███████
██     ██  ██  ██     ██ ██       ██     ██
██     ██  ██  ██     ██ ██       ██     ██
██     ██  ██  ██     ██ ██████   ██     ██
 ██   ██   ██  ██     ██ ██       ██     ██
  ██ ██    ██  ██     ██ ██       ██     ██
   ███    ████ ████████  ████████  ███████
-->

<h2 id="video-prefixed-features">Video Prefixed Features</h2>

	Some user agents, including many TVs, render video and graphics in two
	separate "planes" (bi-plane) with distinct screen characteristics. A set of
	video-prefixed features is provided to describe the video plane.

	Any bi-plane implementation must return values based on the video plane
	for the following features:
	'@media/video-color-gamut';
	'@media/video-dynamic-range'.
	All other features must return values based on the graphics plane.

	Non bi-plane implementations must return the same values for
	video-prefixed features and their non-prefixed counterparts.

<h3 id="video-color-gamut">
Video Color Display Quality: the '@media/video-color-gamut' feature</h3>

	<pre class='descdef mq'>
	Name: video-color-gamut
	Value: srgb | p3 | rec2020
	For: @media
	Type: discrete
	</pre>

The '@media/video-color-gamut' media feature describes the approximate range of colors
	that are supported by the UA and output device's video plane.
	That is, if the UA receives content with colors in the specified space
	it can cause the output device to render the appropriate color,
	or something appropriately close enough.

Value and color space definitions are the same as '@media/color-gamut'.

<h3 id="video-dynamic-range">
Video Dynamic Range: the '@media/video-dynamic-range' feature</h3>

	<pre class='descdef mq'>
	Name: video-dynamic-range
	Value: standard | high
	For: @media
	Type: discrete
	</pre>

'@media/video-dynamic-range' represents the combination of max brightness,
color depth, and contrast ratio that are supported by the UA and output device's
video plane.

Supported values are the same as <a href="#dynamic-range">dynamic-range</a>.

<!--
 ██████   ██████  ████████  ████ ████████  ████████ ████ ██    ██  ██████
██    ██ ██    ██ ██     ██  ██  ██     ██    ██     ██  ███   ██ ██    ██
██       ██       ██     ██  ██  ██     ██    ██     ██  ████  ██ ██
 ██████  ██       ████████   ██  ████████     ██     ██  ██ ██ ██ ██   ████
      ██ ██       ██   ██    ██  ██           ██     ██  ██  ████ ██    ██
██    ██ ██    ██ ██    ██   ██  ██           ██     ██  ██   ███ ██    ██
 ██████   ██████  ██     ██ ████ ██           ██    ████ ██    ██  ██████
-->

<h2 id='mf-scripting'>
Scripting Media Features</h2>

<h3 id="scripting">
Scripting Support: the '@media/scripting' feature</h3>

	<pre class='descdef mq'>
	Name: scripting
	Value: none | initial-only | enabled
	For: @media
	Type: discrete
	</pre>

	The '@media/scripting' media feature is used to query whether scripting languages,
	such as JavaScript,
	are supported on the current document.

	<dl dfn-type=value dfn-for="@media/scripting">
		<dt><dfn>enabled</dfn>
		<dd>
			Indicates that the user agent supports scripting of the page,
			and that scripting in the current document is enabled
			for the lifetime of the document.

		<dt><dfn>initial-only</dfn>
		<dd>
			Indicates that the user agent supports scripting of the page,
			and that scripting in the current document is enabled during the initial page load,
			but is not supported afterwards.
			Examples are printed pages,
			or pre-rendering network proxies
			that render a page on a server
			and send a nearly-static version of the page to the user.

			Issue(503): Should there be an explicit minimum threshold to meet
			before a UA is allowed to claim ''initial-only''?
			Having one would mean authors would know
			what they can depend on,
			and could tailor their scripts accordingly.
			On the other hand, pinpointing that threshold is difficult:
			if it is set too low,
			the scripting facilities that authors can depend on
			may be to constrained to be practical,
			even though actual UAs may potentially
			all support significantly more.
			But trying to set it higher may cause us to exclude
			UAs that do support scripting at loading time,
			but restrict it in some cases based on complex heuristics.
			For instance, conservative definitions likely include at least
			running all inline scripts and firing the DOMContentLoaded event.
			But it does not seem useful for authors to constrain themselves to this
			if most (or maybe all) ''initial-only'' UAs
			also load external scripts (including ''async'' and ''defer'')
			and fire the load event.
			On the other hand,
			requiring external scripts to be loaded
			and the load event to be fired
			could exclude UAs like Opera mini,
			which typically do run them,
			but may decide not to based on timeouts and other heuristics.

		<dt><dfn>none</dfn>
		<dd>
			Indicates that the user agent will not run scripts for this document;
			either it doesn't support a scripting language,
			or the support isn't active for the current document.
	</dl>

	Some user agents have the ability to turn off scripting support on a per script basis or per domain basis,
	allowing some, but not all, scripts to run in a particular document.
	The '@media/scripting' media feature does not allow fine grained detection of which script is allowed to run.
	In this scenario, the value of the '@media/scripting' media feature should be ''scripting/enabled'' or ''scripting/initial-only''
	if scripts originating on the same domain as the document are allowed to run,
	and ''scripting/none'' otherwise.

	Note: A future level of CSS may extend this media feature to allow fine-grained detection of which script is allowed to run.

	<wpt>
		scripting-print-noscript.html
		scripting-print-script.html
		scripting.html
	</wpt>

<!--
 ██████  ██     ██  ██████  ████████  ███████  ██     ██       ██     ██  ███████
██    ██ ██     ██ ██    ██    ██    ██     ██ ███   ███       ███   ███ ██     ██
██       ██     ██ ██          ██    ██     ██ ████ ████       ████ ████ ██     ██
██       ██     ██  ██████     ██    ██     ██ ██ ███ ██       ██ ███ ██ ██     ██
██       ██     ██       ██    ██    ██     ██ ██     ██       ██     ██ ██  ██ ██
██    ██ ██     ██ ██    ██    ██    ██     ██ ██     ██       ██     ██ ██    ██
 ██████   ███████   ██████     ██     ███████  ██     ██       ██     ██  █████ ██
-->

<h2 id='custom-mq'>
Custom Media Queries</h2>

	When designing documents that use media queries,
	the same media query may be used in multiple places,
	such as to qualify multiple ''@import'' statements.
	Repeating the same media query multiple times is an editing hazard;
	an author making a change must edit every copy in the same way,
	or suffer from difficult-to-find bugs in their CSS.

	To help ameliorate this,
	this specification defines a method of defining <a>custom media queries</a>,
	which are simply-named aliases for longer and more complex media queries.
	In this way, a media query used in multiple places can instead be assigned to a <a>custom media query</a>,
	which can be used everywhere,
	and editing the media query requires touching only one line of code.

	A <dfn>custom media query</dfn> is defined with the ''@custom-media'' rule:

	<pre class='prod'>
		<dfn>@custom-media</dfn> = @custom-media <<extension-name>> [ <<media-query-list>> | true | false ] ;
	</pre>

	The <<extension-name>> can then be used in a <a>media feature</a>.
	It <strong>must</strong> be used in a <a>boolean context</a>;
	using them in a normal or <a>range context</a> is a syntax error.
	If a <<media-query-list>> is given,
	the <a>custom media query</a> evaluates to true
	if the <<media-query-list>> it represents evaluates to true,
	and false otherwise.
	If <dfn value for="@custom-media">true</dfn> or <dfn value for="@custom-media">false</dfn> is given,
	the <a>custom media query</a> evaluates to true or false, respectively.

	<div class=example>
		The [=custom media query=] is evaluated logically, not treated as a textual substitution.
		Take the following code snippet for instance:
		<pre><code class=lang-css>
		/* --modern targets modern devices that support color or hover */
		@custom-media --modern (color), (hover);

		@media (--modern) and (width > 1024px) {
			.a { color: green; }
		}
		</code></pre>
		It is equivalent to:
		<pre><code class=lang-css>
		@media ((color) or (hover)) and (width > 1024px) {
			.a { color: green; }
		}
		</code></pre>

		Processing it as if it meant the following would be incorrect:
		<pre><code class=lang-css>
		@media (color), (hover) and (width > 1024px) {
			.a { color: green; }
		}
		</code></pre>
	</div>

	A ''@custom-media'' rule can refer to other <a>custom media queries</a>.
	However, loops are forbidden,
	and a <a>custom media query</a> must not be defined in terms of itself or
	of another <a>custom media query</a> that directly or indirectly refers to it.
	Any such attempt of defining a <a>custom media query</a> with a circular dependency
	must cause all the <a>custom media queries</a> in the loop to fail to be defined.

	If multiple ''@custom-media'' rules declare the same <<extension-name>>,
	the truth value is based on the last one alone,
	ignoring all previous declarations of the same <<extension-name>>.

	Note: For error handling purposes,
	an undefined <a>media feature</a> is different from
	a <a>media feature</a> that evaluates to false.
	See [[mediaqueries-4#error-handling]] for details.

	<div class='example'>
		For example, if a responsive site uses a particular breakpoint in several places,
		it can alias that with a reasonable name:

		<pre>
			@custom-media --narrow-window (max-width: 30em);

			@media (--narrow-window) {
				/* narrow window styles */
			}
			@media (--narrow-window) and (script) {
				/* special styles for when script is allowed */
			}
			/* etc */
		</pre>
	</div>

<h3 id='script-custom-mq'>
Script-based Custom Media Queries</h3>

	<div class='issue'>
		Define a map of names to values for JS.
		Values can be either a MediaQueryList object or a boolean,
		in which case it's treated identically to the above,
		or can be a number or a string,
		in which case it's treated like a normal MQ,
		and can use the normal or range context syntax.
		Like:

		<pre>
			&lt;script>
			CSS.customMedia.set('--foo', 5);
			&lt;/script>
			&lt;style>
			@media (_foo: 5) { ... }
			@media (_foo < 10) { ... }
			&lt;/style>
		</pre>
	</div>

<!--
 ██████   ██████   ██████   ███████  ██     ██
██    ██ ██    ██ ██    ██ ██     ██ ███   ███
██       ██       ██       ██     ██ ████ ████
██        ██████   ██████  ██     ██ ██ ███ ██
██             ██       ██ ██     ██ ██     ██
██    ██ ██    ██ ██    ██ ██     ██ ██     ██
 ██████   ██████   ██████   ███████  ██     ██
-->

<h2 id='custom-mq-cssom'>
CSSOM</h2>

The {{CSSCustomMediaRule}} interface represents a ''@custom-media'' rule.

<pre class="idl" export>
typedef (MediaList or boolean) CustomMediaQuery;

[Exposed=Window]
interface CSSCustomMediaRule : CSSRule {
	readonly attribute CSSOMString name;
	readonly attribute CustomMediaQuery query;
};
</pre>

<dl dfn-type=attribute dfn-for=CSSCustomMediaRule>
	<dt><dfn>name</dfn>
	<dd>
		Returns a CSSOMString representing the <<extension-name>> of the ''@custom-media'' rule.

	<dt><dfn>query</dfn>
	<dd>
		Represents the value of the <a>custom media query</a>.
		The returned {{CustomMediaQuery}} will be one of the following:
		<ul>
			<li>A {{MediaList}} object,
			if the rule was defined with a <<media-query-list>>.
			<li>The boolean true,
			if the rule was defined with the value <a value for="@custom-media">true</a>.
			<li>The boolean false,
			if the rule was defined with the value <a value for="@custom-media">false</a>.
		</ul>
</dl>

<wpt>
	at-custom-media-cssom.html
</wpt>

<!--
██     ██  ██████  ████████ ████████  ████████  ████████  ████████ ████████  ██████
██     ██ ██    ██ ██       ██     ██ ██     ██ ██     ██ ██       ██       ██    ██
██     ██ ██       ██       ██     ██ ██     ██ ██     ██ ██       ██       ██
██     ██  ██████  ██████   ████████  ████████  ████████  ██████   ██████    ██████
██     ██       ██ ██       ██   ██   ██        ██   ██   ██       ██             ██
██     ██ ██    ██ ██       ██    ██  ██        ██    ██  ██       ██       ██    ██
 ███████   ██████  ████████ ██     ██ ██        ██     ██ ████████ ██        ██████
-->

<h2 id='mf-user-preferences'>
User Preference Media Features</h2>

<h3 id="prefers-reduced-motion">
Detecting the desire for less motion on the page: the '@media/prefers-reduced-motion' feature</h3>

	<pre class='descdef mq'>
	Name: prefers-reduced-motion
	Value: no-preference | reduce
	For: @media
	Type: discrete
	</pre>

	The '@media/prefers-reduced-motion' media feature is used to detect if the user
	has requested the system minimize the amount of non-essential motion
	it uses.

	<dl dfn-type=value dfn-for="@media/prefers-reduced-motion">
		<dt><dfn>no-preference</dfn>
		<dd>
			Indicates that the user has made no preference known
			to the system. This keyword value evaluates as false
			in the <a>boolean context</a>.

		<dt><dfn>reduce</dfn>
		<dd>
			Indicates that user has notified the system
			that they prefer an interface that
			removes or replaces the types of motion-based animation
			that either trigger discomfort for those with vestibular motion sensitivity,
			or distraction for those with attention deficits.
	</dl>

	<wpt>
		prefers-reduced-motion.html
	</wpt>

<h3 id="prefers-reduced-transparency">
Detecting the desire for reduced transparency on the page: the '@media/prefers-reduced-transparency' feature</h3>

	<pre class='descdef mq'>
	Name: prefers-reduced-transparency
	Value: no-preference | reduce
	For: @media
	Type: discrete
	</pre>

	The '@media/prefers-reduced-transparency' media feature is used to detect if the user
	has requested the system minimize the amount of transparent or translucent
	layer effects it uses.

	<dl dfn-type=value dfn-for="@media/prefers-reduced-transparency">
		<dt><dfn>no-preference</dfn>
		<dd>
			Indicates that the user has made no preference known
			to the system. This keyword value evaluates as false
			in the <a>boolean context</a>.

		<dt><dfn>reduce</dfn>
		<dd>
			Indicates that user has notified the system that they
			prefer an interface that minimizes the amount of
			transparent or translucent layer effects.
	</dl>

	ISSUE: How does this interact with preferences around e.g. pattern fills and backgrounds?
	They're not about transparency, but they also interfere with shape recognition.

	<wpt>
		prefers-reduced-transparency.html
	</wpt>

<h3 id="prefers-contrast">
Detecting the desire for increased or decreased color contrast from elements on the page: the '@media/prefers-contrast' feature</h3>

	<pre class='descdef mq'>
	Name: prefers-contrast
	Value: no-preference | less | more | custom
	For: @media
	Type: discrete
	</pre>

	The '@media/prefers-contrast' media feature is used to detect
	if the user has requested more or less contrast in the page.
	This could be responded to, for example,
	by adjusting the contrast ratio between adjacent colors,
	or by changing how much elements stand out visually,
	such as by adjusting their borders.

	<dl dfn-type=value dfn-for="@media/prefers-contrast">
		<dt><dfn>no-preference</dfn>
		<dd>
			Indicates that the user has made no preference known
			to the system. This keyword value evaluates as false
			in the <a>boolean context</a>.

		<dt><dfn>less</dfn>
		<dd>
			Indicates that user has notified the system that they
			prefer an interface that has a lower level of contrast.

		<dt><dfn>more</dfn>
		<dd>
			Indicates that user has notified the system that they
			prefer an interface that has a higher level of contrast.

		<dt><dfn>custom</dfn>
		<dd>
			Indicates that the user has indicated
			wanting a specific set of colors to be used,
			but the contrast implied by these particular colors
			is such that neither ''more'' nor ''less'' match.

			Note: This value will match for users of [=forced colors mode=]
			who have picked a palette that is neither particularly high nor low
			contrast.
			See [[#forced-colors]].

			<div class=example>
				A user calling for
				<span style="background: #B64000; color: #00FFFF;">cyan text over a rust background</span>
				is not--
				at least in terms of luminosity--
				expressing a need for particularly high or low contrast,
				but this is not a lack of a preference either.
			</div>
	</dl>

	<div class=note>
		Note: Authors can respond to specific user preferences for more or less
		contrast using ''prefers-contrast: more'' or ''prefers-contrast: less'',
		as appropriate.

		Using an unqualified <code class=lang-css>@media (prefers-contrast) { … }</code>
		to apply high contrast styles is incorrect and user-hostile,
		as it would also impose high contrast styles to people who have requested the exact opposite.

		However, it is also common to reduce visual clutter and color complexity
		in response to both high and low contrast preferences.
		In that case, it is appropriate to use <code class=lang-css>@media (prefers-contrast) { … }</code>
		without specifying ''prefers-contrast/more'' or ''prefers-contrast/less'',
		to do things like replacing background images with plain colors,
		turning off decorative gradients,
		or replacing border images or box shadows with simple solid borders.
		As ''prefers-contrast: custom''--
		like ''prefers-contrast: more'' or ''prefers-contrast: less''--
		evaluates to true in a [=boolean context=],
		such simplifications would also benefit users of [=forced colors mode=],
		even when their colors of choice do not result
		in a particularly high or low contrast.
		This is desirable,
		as the reduced palette enforced by [=forced colors mode=]
		calls for some visual simplification of the page.
	</div>

	<div class=example>
		Preference for more or less contrast may arise
		from a variety of different situations.
		Here are some examples:

		<ul>
			<li>
				Many users have difficulty
				reading text that has a small difference in contrast to the text
				background and would prefer a larger contrast.

			<li>
				People suffering from migraine
				may find strongly contrasting pages
				to be visually painful
				and would prefer a low contrast.

			<li>
				Some people with dyslexia find high contrast text hard to read,
				as they feel that the letters shine / sparkle as if backlit by too bright a light,
				and find low contrast to be more comfortable.

			<li>
				Environmental factors may also lead
				a user to prefer more or less contrast.
				See also [[#auto-pref]].
		</ul>

		Issue: This list should be refined and expanded.
	</div>

	<wpt>
		prefers-contrast.html
	</wpt>

<h3 id="forced-colors">
Detecting Forced Colors Mode: the '@media/forced-colors' feature</h3>

	<pre class='descdef mq'>
	Name: forced-colors
	Value: none | active
	For: @media
	Type: discrete
	</pre>

	<dl dfn-type=value dfn-for="@media/forced-colors">
		<dt><dfn>active</dfn>
		<dd>
			Indicates that <a>forced colors mode</a> is active:
			the user agent enforces a user-chosen limited color palette on the page,
			The UA will provide the color palette to authors
			through the CSS system color keywords.
			See [[css-color-adjust-1#forced]] for details.

			<div class=advisement>
				This does <em>not</em> necessarily indicate
				a preference for more contrast.
				The colors have been forcibly adjusted
				to match the preference of the user,
				but that preference can be for less or more contrast,
				or some other arrangement that is neither particularly low or high contrast.
			</div>

			In addition to ''forced-colors: active'',
			the user agent must also match
			one of ''prefers-contrast: more''
			or ''prefers-contrast: less''
			if it can determine
			that the forced color palette chosen by the user
			has a particularly high or low contrast,
			and must make ''prefers-contrast: custom'' match otherwise.

			Similarly,
			if the forced color palette chosen by the user
			fits within one of the color schemes described by '@media/prefers-color-scheme',
			the corresponding value must also match.

		<dt><dfn>none</dfn>
		<dd>
			[=Forced colors mode=] is not active.
	</dl>

	<div class=example>
		When [=forced colors mode=] is active,
		the only colors that are available to the author are [=system colors=].
		The user agent will enforce this limited palette automatically,
		but the author may choose a different way of using these colors,
		using the ''forced-colors'' media feature to detect when it is appropriate to do so.
	</div>

	<wpt>
		forced-colors.html
	</wpt>

<h3 id="prefers-color-scheme">
Detecting the desire for light or dark color schemes: the '@media/prefers-color-scheme' feature</h3>

	<pre class='descdef mq'>
	Name: prefers-color-scheme
	Value: light | dark
	For: @media
	Type: discrete
	</pre>

	The '@media/prefers-color-scheme' media feature reflects the user's
	desire that the page use a light or dark color theme.

	<dl dfn-type=value dfn-for="@media/prefers-color-scheme">
		<dt><dfn>light</dfn>
		<dd>
			Indicates that user has expressed the preference for
			a page that has a light theme (dark text on light background),
			or has not expressed an active preference
			(and thus should receive the "web default" of a light theme).

		<dt><dfn>dark</dfn>
		<dd>
			Indicates that user has expressed the preference for
			a page that has a dark theme (light text on dark background).
	</dl>

	Note: The values for this feature might be expanded in the future
	(to express a more active preference for light color schemes,
	or preferences for other types of color schemes like "sepia").
	As such, the most future-friendly way to use this media feature
	is by negation such as ''(prefers-color-scheme: dark)'' and ''(not (prefers-color-scheme: dark))'',
	which ensures that new values fall into at least one of the styling blocks.

	The method by which the user expresses their preference can vary.
	It might be a system-wide setting exposed by the Operating System,
	or a setting controlled by the user agent.

	Note: User preferences can also vary by medium.
	For example, a user may prefer dark themes on a glowing screen,
	but light themes when printing
	(to save ink
	and/or because inked text on blank paper prints better
	than blank letterforms knocked out of an inked background).
	UAs are expected to take such variances into consideration
	so that '@media/prefers-color-scheme' reflects preferences appropriate to the medium
	rather than preferences taken out of context.

	If evaluated in an embedded SVG document
	using the "Secure Animated" embedding mode,
	the preferred color scheme must reflect the value of the [=used color scheme=]
	on the embedding node in the embedding document.

	<details class=note>
		<summary>Why do this?</summary>

		While the outermost document needs to get the user's preference directly,
		it's more useful for an embedded document
		to use the color scheme of its surrounding embedding context,
		so it matches the surrounding content.

		However, this enables communication
		from the embedding document to the embedded document,
		so it's currently restricted to SVG's
		using the "Secure Animated" mode,
		which can't load external resources
		or run script,
		and thus can't respond to the color scheme
		in any way observable to the outside world.

		Whether or not to do similar for iframes,
		and under what conditions,
		is being discussed in
		<a href="https://github.com/w3c/csswg-drafts/issues/7213/">Issue 7213</a>.
	</details>

	<div class=note>
		This feature, like the other 'prefers-*' features,
		previously had a <css>no-preference</css> value
		to indicate an author not expressing an active preference.
		However, user agents converged on expressing the "default" behavior
		as a ''light'' preference,
		and never matching <css>no-preference</css>.

		If a future user agent wishes to expose a difference
		between "no preference" and "really wants a light display",
		please contact the CSSWG to discuss this.
	</div>

	<wpt>
		prefers-color-scheme-svg-as-image.html
		prefers-color-scheme-svg-image-normal-with-meta-dark.html
		prefers-color-scheme-svg-image-normal-with-meta-light.html
		prefers-color-scheme-svg-image-normal.html
		prefers-color-scheme-svg-image.html
		prefers-color-scheme.html
	</wpt>

<h3 id="prefers-reduced-data">
Detecting the desire for reduced data usage when loading a page: the '@media/prefers-reduced-data' feature</h3>

	Issue(10076): This feature may be an undesired source of fingerprinting,
	with a bias towards low income with limited data.

	<pre class='descdef mq'>
	Name: prefers-reduced-data
	Value: no-preference | reduce
	For: @media
	Type: discrete
	</pre>

	The '@media/prefers-reduced-data' media feature is used to detect if the user
	has a preference for being served alternate content that uses less
	data for the page to be rendered.

	<dl dfn-type=value dfn-for="@media/prefers-reduced-data">
		<dt><dfn>no-preference</dfn>
		<dd>
			Indicates that the user has made no preference known
			to the system. This keyword value evaluates as false
			in the <a>boolean context</a>.

		<dt><dfn>reduce</dfn>
		<dd>
			Indicates that user has expressed the preference for
			lightweight alternate content.
	</dl>

	The method by which the user expresses their preference can vary.
	It might be a system-wide setting exposed by the Operating System,
	or a setting controlled by the user agent. User agents may consider
	setting this based on the same user or system preference as they use to
	set the <a href="https://wicg.github.io/savedata/">Save-Data</a>
	HTTP request header.

	Note: User agents are encouraged to use their own user centered discretion
	when handling a toggle of this value,
	whether it's toggled post page load or during page load.
	A primary goal could be to not download unnecessary data.
	Consider, if a page is already loaded with high quality assets
	and the user changes their preference to reduced,
	the page could perhaps not update the document right away,
	instead wait for an explicit page reload invocation from the user.
	Consider also, if a page is taking a long time to download
	and a user changes their preference to reduced,
	this could be a nice point to save the user's bandwidth
	and immediately switch to downloading smaller assets.
	User agents are free to implement logic
	as they see appropriate for situations like these,
	and also ought to be aware the situations exist.

	<div class="example">
		For example, a site could honour the preference of a user who
		has turned on data-saving mode by serving a smaller image.

		<pre>
		.image {
			background-image: url("images/heavy.jpg");
		}

		@media (prefers-reduced-data: reduce) {
			/* Save-Data: On */
			.image {
				background-image: url("images/light.jpg");
			}
		}
		</pre>
	</div>

	<wpt>
		prefers-reduced-data.html
	</wpt>

<h3 id=auto-pref>
Automatic handling of User Preferences</h3>

	User agents may have explicit settings allowing users to indicate their preferences
	or may make the determination based on settings in the underlying operating system.
	User agents may also automatically infer the preferences of the user
	based on knowledge about the device, the environment, etc.
	In such case, it is recommended that they also offer a way for users to opt out of
	or override the automatically determined preferences.

	<div class=example>
		In addition to allowing users to explicitly choose
		between a preference for a ''prefers-color-scheme/light'' or ''prefers-color-scheme/dark'' color scheme,
		a user agent could have a mode where the determination is automatically made based on the current time,
		expressing a preference for ''prefers-color-scheme/dark'' between sunset and dawn.
	</div>

	<div class=example>
		Depending on the type of display used,
		changes in the ambient light level may make the reading experience difficult or uncomfortable.

		For instance, liquid crystal displays can be washed out and very hard to read
		in brightly lit environments.
		A device with such a screen and with an ambient light sensor
		could automatically switch '@media/prefers-contrast' to ''prefers-contrast/more''
		when it detects conditions that would make the screen difficult to read.
		A user agent on a device with an e-ink display
		would not make the same adjustment,
		as such displays remain readable in bright daylight.

		In the opposite situation,
		user agents running of device with a light-emitting screen (LCD, OLED, etc.)
		and an ambient light sensor
		could automatically switch '@media/prefers-contrast' to ''prefers-contrast/less''
		and '@media/prefers-color-scheme' to ''prefers-color-scheme/dark''
		when used in a dim environment
		where excessive contrast and brightness would be distracting or uncomfortable to the reader.
	</div>

	<div class=example>
		A user agent could automatically switch between ''prefers-reduced-data: no-preference'' and ''prefers-reduced-data/reduce''
		depending on whether the network connection in use
		allows for unlimited data or is on a metered plan.
	</div>

<h2 id=script-control-user-prefs>
Script Control of User Preferences</h2>

It is common for website authors to want to respect the user's system preferences while also allowing
those preferences to be overridden. To help with this, this specification defines a way for authors to
override the [[#mf-user-preferences]] using the {{PreferenceManager}} interface.

This override allows the preference to integrate with various platform features that are affected by these preferences.

<h3 id=navigator-interface>
Extensions to the {{Navigator}} interface</h3>

<script type=idl>
[Exposed=Window, SecureContext]
partial interface Navigator {
	[SameObject] readonly attribute PreferenceManager preferences;
};
</script>

<h4 id=preferences-attribute>
{{preferences}} attribute</h4>

When getting the {{preferences}} attribute always return the same instance of the {{PreferenceManager}} object.

### {{PreferenceManager}} interface ### {#preference-manager}

<script type=idl>
[Exposed=Window, SecureContext]
interface PreferenceManager {
	readonly attribute PreferenceObject colorScheme;
	readonly attribute PreferenceObject contrast;
	readonly attribute PreferenceObject reducedMotion;
	readonly attribute PreferenceObject reducedTransparency;
	readonly attribute PreferenceObject reducedData;
};
</script>

<h4 id=color-scheme-attribute>
{{colorScheme}} attribute</h4>

The {{colorScheme}} attribute is a {{PreferenceObject}} used to override the user's preference for the color scheme of the site.
This is modeled after the [[#prefers-color-scheme]].

<div algorithm='get valid values for colorScheme'>
	The <dfn>get valid values for colorScheme</dfn> algorithm, when invoked, must run these steps:

	1. Let |validValues| be a new empty [=sequence=].
	1. Add ''light'' to |validValues|.
	1. Add ''dark'' to |validValues|.
	1. Return |validValues|.
</div>

If an override is set for this preference:
- The user agent MUST use this override for the [[#prefers-color-scheme]] in all stylesheets applied to an [=origin=] including the UA style sheet.
- The user agent MUST also use this override when queried via `matchMedia()` from [[cssom-view#extensions-to-the-window-interface]].
- The user agent MUST also use this override when calculating the [=used color scheme=].
- The user agent MUST also use this override when sending [[USER-PREFERENCE-MEDIA-FEATURES-HEADERS#sec-ch-prefers-color-scheme]].
- The user agent MUST also use this override for any UA features that are normally affected by [[#prefers-color-scheme]].

<h4 id=contrast-attribute>
{{contrast}} attribute</h4>

The {{contrast}} attribute is a {{PreferenceObject}} used to override the user's preference for the contrast of the site.
This is modeled after the [[#prefers-contrast]].

<div algorithm='get valid values for contrast'>
	The <dfn>get valid values for contrast</dfn> algorithm, when invoked, must run these steps:

	1. Let |validValues| be a new empty [=sequence=].
	1. Add ''@media/prefers-contrast/more'' to |validValues|.
	1. Add ''@media/prefers-contrast/less'' to |validValues|.
	1. Add ''@media/prefers-contrast/no-preference'' to |validValues|.
	1. Return |validValues|.
</div>

If an override is set for this preference:
- The user agent MUST use this override for the [[#prefers-contrast]] in all stylesheets applied to an [=origin=] including the UA style sheet.
- The user agent MUST also use this override when queried via `matchMedia()` from [[cssom-view#extensions-to-the-window-interface]].
- The user agent MUST also use this override when sending [[USER-PREFERENCE-MEDIA-FEATURES-HEADERS#sec-ch-prefers-contrast]].
- The user agent MUST also use this override for any UA features that are normally affected by [[#prefers-contrast]].

Note: Unlike the media feature this preference is NOT able to be set to ''@media/prefers-contrast/custom'' as this is tightly coupled to the [[#forced-colors]].

<h4 id=reduced-motion-attribute>
{{reducedMotion}} attribute</h4>

The {{reducedMotion}} attribute is a {{PreferenceObject}} used to override the user's preference for reduced motion on the site.
This is modeled after the [[#prefers-reduced-motion]].

<div algorithm='get valid values for reducedMotion'>
	The <dfn>get valid values for reducedMotion</dfn> algorithm, when invoked, must run these steps:

	1. Let |validValues| be a new empty [=sequence=].
	1. Add ''@media/prefers-reduced-motion/reduce'' to |validValues|.
	1. Add ''@media/prefers-reduced-motion/no-preference'' to |validValues|.
	1. Return |validValues|.
</div>

If an override is set for this preference:
- The user agent MUST use this override for the [[#prefers-reduced-motion]] in all stylesheets applied to an [=origin=] including the UA style sheet.
- The user agent MUST also use this override when queried via `matchMedia()` from [[cssom-view#extensions-to-the-window-interface]].
- The user agent MUST also use this override when sending [[USER-PREFERENCE-MEDIA-FEATURES-HEADERS#sec-ch-prefers-reduced-motion]].
- The user agent MUST also use this override for any UA features that are normally affected by [[#prefers-reduced-motion]].

Note: An example of a UA feature that is affected by this preference could be disabling smooth scrolling, or pausing marquee elements.

<h4 id=reduced-transparency-attribute>
{{reducedTransparency}} attribute</h4>

The {{reducedTransparency}} attribute is a {{PreferenceObject}} used to override the user's preference for reduced transparency on the site.
This is modeled after the [[#prefers-reduced-transparency]].

<div algorithm='get valid values for reducedTransparency'>
	The <dfn>get valid values for reducedTransparency</dfn> algorithm, when invoked, must run these steps:

	1. Let |validValues| be a new empty [=sequence=].
	1. Add ''@media/prefers-reduced-transparency/reduce'' to |validValues|.
	1. Add ''@media/prefers-reduced-transparency/no-preference'' to |validValues|.
	1. Return |validValues|.
</div>

If an override is set for this preference:
- The user agent MUST use this override for the [[#prefers-reduced-transparency]] in all stylesheets applied to an [=origin=] including the UA style sheet.
- The user agent MUST also use this override when queried via `matchMedia()` from [[cssom-view#extensions-to-the-window-interface]].
- The user agent MUST also use this override when sending [[USER-PREFERENCE-MEDIA-FEATURES-HEADERS#sec-ch-prefers-reduced-transparency]].
- The user agent MUST also use this override for any UA features that are normally affected by [[#prefers-reduced-transparency]].

<h4 id=reduced-data-attribute>
{{reducedData}} attribute</h4>

The {{reducedData}} attribute is a {{PreferenceObject}} used to override the user's preference for reduced data usage on the site.
This is modeled after the [[#prefers-reduced-data]].

<div algorithm='get valid values for reducedData'>
	The <dfn>get valid values for reducedData</dfn> algorithm, when invoked, must run these steps:

	1. Let |validValues| be a new empty [=sequence=].
	1. Add ''@media/prefers-reduced-data/reduce'' to |validValues|.
	1. Add ''@media/prefers-reduced-data/no-preference'' to |validValues|.
	1. Return |validValues|.
</div>

If an override is set for this preference:
- The user agent MUST use this override for the [[#prefers-reduced-data]] in all stylesheets applied to an [=origin=] including the UA style sheet.
- The user agent MUST also use this override when queried via `matchMedia()` from [[cssom-view#extensions-to-the-window-interface]].
- The user agent MUST also use this override when sending [[SAVEDATA#save-data-request-header-field]].
- The user agent MUST also use this override when calculating the [[SAVEDATA#savedata-attribute]].
- The user agent MUST also use this override for any UA features that are normally affected by [[#prefers-reduced-data]].

<h4 id=preference-object-interface>
{{PreferenceObject}} interface</h4>

<script type=idl>
[Exposed=Window, SecureContext]
interface PreferenceObject : EventTarget {
	readonly attribute DOMString? override;
	readonly attribute DOMString value;
	readonly attribute FrozenArray<DOMString> validValues;

	undefined clearOverride();
	Promise<undefined> requestOverride(DOMString? value);

	attribute EventHandler onchange;
};
</script>

<h5 id=override-attribute>
{{override}} attribute</h5>

<div algorithm='get preference override'>
	The <dfn attribute for=PreferenceObject>override</dfn> attribute, when accessed, must run these steps:

	1. Let |preference| be the preference object's name.
	1. Let |override| be null.
	1. If an override for |preference| exists, set |override| to the value of that override.
	1. Return |override|.
</div>

<h5 id=preference-value-attribute>
{{PreferenceObject/value}} attribute</h5>

<div algorithm='get preference value'>
	The <dfn attribute for=PreferenceObject>value</dfn> attribute, when accessed, must run these steps:

	1. Let |preference| be the preference object's name.
	1. Let |value| be null.
	1. If an override for |preference| exists, set |value| to the value of that override.
	1. If |value| is null, set |value| to the UA value of the preference.
	1. Return |value|.
</div>

<h5 id=valid-values-attribute>
{{validValues}} attribute</h5>

<div algorithm>
	The <dfn attribute for=PreferenceObject>validValues</dfn> attribute, when accessed, must run these steps:

		<ol>
			<li>Let |preference| be the preference object's name.

			<li>Switch on |preference|:
				<dl class="switch">
				 <dt>"{{colorScheme}}"</dt>
				 <dd>Return the result of [=get valid values for colorScheme=].</dd>
				 <dt>"{{contrast}}"</dt>
				 <dd>Return the result of [=get valid values for contrast=].</dd>
				 <dt>"{{reducedMotion}}"</dt>
				 <dd>Return the result of [=get valid values for reducedMotion=].</dd>
				 <dt>"{{reducedTransparency}}"</dt>
				 <dd>Return the result of [=get valid values for reducedTransparency=].</dd>
				 <dt>"{{reducedData}}"</dt>
				 <dd>Return the result of [=get valid values for reducedData=].</dd>
			 </dl>
		</ol>
</div>

<h5 id=onchange-attribute>
{{onchange}} event handler attribute</h5>

The <dfn attribute for=PreferenceObject>onchange</dfn> attribute is an [=event handler IDL attribute=] for
the {{onchange}} [=event handler=], whose [=event handler event type=]
is <dfn class="event" data-dfn-for="PreferenceObject">change</dfn>.

<div algorithm="update steps">
Whenever the [=user agent=] is aware that the state of a {{PreferenceObject}}
instance |value| has changed, it runs the <dfn algorithm for="PreferenceObject">{{PreferenceObject}}
update steps</dfn>:

1. Let |preference| be the {{PreferenceObject}} object that |value| is associated with.
1. If [=this=]'s [=relevant global object=] is a {{Window}} object, then:
	1. Let |document| be |preference|'s [=relevant global object=]'s [=associated Document=].
	1. If |document| is null or |document| is not [=Document/fully active=], terminate this algorithm.
1. <a>Fire an event</a> named <code>change</code> at |preference|.

<h5 id=request-override-method>
{{requestOverride()}} method</h5>

<div algorithm='request preference override'>
	The <dfn method for=PreferenceObject>requestOverride(value)</dfn> method, when invoked, must run these steps:

	1. Let |result| be [=a new promise=].
	1. Let |allowed| be false.
	1. Set |allowed| to the result of executing a UA defined algorithm for deciding whether the request is allowed.
	1. If |allowed| is false, return [=a promise rejected with=] a "{{NotAllowedError}}" {{DOMException}}.
	1. Let |value| be the method's argument.
	1. Let |result| be [=a new promise=].
	1. If |value| is null or the empty string:
		1. Run {{clearOverride}}.
		1. [=Resolve=] and return |result|.
	1. Let |currentValue| be the preference object's |value|.
	1. Let |validValues| be null.
	1. Switch on |preference|:
			<dl class="switch">
			 <dt>"{{colorScheme}}"</dt>
			 <dd>Set |validValues| to the result of [=get valid values for colorScheme=].</dd>
			 <dt>"{{contrast}}"</dt>
			 <dd>Set |validValues| to the result of [=get valid values for contrast=].</dd>
			 <dt>"{{reducedMotion}}"</dt>
			 <dd>Set |validValues| to the result of [=get valid values for reducedMotion=].</dd>
			 <dt>"{{reducedTransparency}}"</dt>
			 <dd>Set |validValues| to the result of [=get valid values for reducedTransparency=].</dd>
			 <dt>"{{reducedData}}"</dt>
			 <dd>Set |validValues| to the result of [=get valid values for reducedData=].</dd>
		 </dl>
	1. If |value| is not in |validValues|:
		1. [=Reject=] |result| with a "{{TypeError}}" {{DOMException}}.
		1. Return |result|.
	1. Let |previousOverride| be null.
	1. If an override for |preference| exists, set |previousOverride| to the value of that override.
	1. If |value| is different from |previousOverride|:
		1. Set the preference override for |preference| to |value|.
	1. If |previousOverride| is null, then:
		1. If |value| is the same as |currentValue|, then:
			1. <a>Fire an event</a> named <code>change</code> at [=this=].
	1. [=Resolve=] and return |result|.
</div>

Issue: This algorithm needs more detail on what exactly setting the preference override does.

Issue: Is TypeError correct here?

Note: The `change` event is fired when the computed value changes, but when a new override is set it is also fired if the value hasn't changed.

<h5 id=clear-override-method>
{{clearOverride()}} method</h5>

<div algorithm='clear preference override'>
	The <dfn method for=PreferenceObject>clearOverride()</dfn> method, when invoked, must run these steps:

	1. Let |preference| be the preference object's name.
	1. Let |override| be null.
	1. If an override for |preference| exists, set |override| to the value of that override.
	1. If |override| is null, then return.
	1. Clear the override for |preference|.
	1. Let |newValue| be the preference object's value.
	1. If |newValue| is equal to |override|, then:
	1. <a>Fire an event</a> named <code>change</code> at [=this=].
</div>

Note: The `change` event is fired when the computed value changes, but when an override is cleared it is also fired if the value hasn't changed.

<!--
████  ██████   ██████  ██     ██ ████████  ██████
 ██  ██    ██ ██    ██ ██     ██ ██       ██    ██
 ██  ██       ██       ██     ██ ██       ██
 ██   ██████   ██████  ██     ██ ██████    ██████
 ██        ██       ██ ██     ██ ██             ██
 ██  ██    ██ ██    ██ ██     ██ ██       ██    ██
████  ██████   ██████   ███████  ████████  ██████
-->

<!--
<h2 id='assorted-issues'>
Assorted Issues</h2>

	<div class='issue'>
		We need a media feature (or set of media features) to detect the type of keyboard available.
		It should be able to distinguish between full computer keyboards, phone dial pads, tv remotes, or virtual keyboards.
		As an attempt at an exhaustive list is likely to fail,
		finding atomic features to decompose these into would be preferable,
		but these remain to be identified.

		<ul>
			<li>always vs in text forms only
			<li>just numbers vs free alphanumeric input vs full ime support
			<li>work properly vs horrible lag like on a tv remove
		</ul>

		How much is actually useful for styling?
	</div>

	<div class='issue'>
		Example sets of MQs that would match on different types of devices

		<ul>
			<li>printer: update:none, pointer:none, hover:none, overflow-block: paged, overflow-inline: none
			<li>eink with stylus: update: slow, pointer:fine, hover:none, overflow-block: paged, overflow-inline: none
			<li>tv: update: fast, pointer: none, hover: none: overflow-block: none, overflow-inline: none
			<li>tablet: update: fast, pointer coarse, hover none, overflow-block: scroll, overflow-inline: scroll
			<li>wii: update: fast, pointer: coarse, hover: yes, overflow-block: scroll, overflow-inline: scroll
			<li>Chromebook pixel: update: fast, pointer: coarse *and* fine, hover: over, overflow-block: scroll, overflow-inline: scroll
			<li>Glass: update: fast, pointer: coarse, hover: none, overflow-block: none, overflow-inline: none
			<li>XTERM: update: fast, pointer:none, hover:none, grid:1, overflow-block: scroll, overflow-inline: none

		</ul>
	</div>

	<div class='issue'>
		<a href="http://lists.w3.org/Archives/Public/www-style/2013Mar/0448.html">http://lists.w3.org/Archives/Public/www-style/2013Mar/0448.html</a>

		MQ for detecting if the device is willing to display/print backgrounds and other ink-hungry properties.
	</div>

	<p class="issue">
		Another media feature should probably be added to deal with the type of resolution authors want to know to deal with monochrome printing.
-->

<!--
████████  ████████ ████████  ████████  ████████  ██████     ███    ████████ ████████ ████████
██     ██ ██       ██     ██ ██     ██ ██       ██    ██   ██ ██      ██    ██       ██     ██
██     ██ ██       ██     ██ ██     ██ ██       ██        ██   ██     ██    ██       ██     ██
██     ██ ██████   ████████  ████████  ██████   ██       ██     ██    ██    ██████   ██     ██
██     ██ ██       ██        ██   ██   ██       ██       █████████    ██    ██       ██     ██
██     ██ ██       ██        ██    ██  ██       ██    ██ ██     ██    ██    ██       ██     ██
████████  ████████ ██        ██     ██ ████████  ██████  ██     ██    ██    ████████ ████████
-->

<h2 id='mf-deprecated'>
Appendix A: Deprecated Media Features</h2>

	<p>The following <a>media features</a> are <strong>deprecated</strong>. They
	are kept for backward compatibility, but are not appropriate for newly
	written style sheets. Authors must not use them. User agents must support them
	as specified.

	<p class="note">To query for the size of the viewport (or the page box
	on page media), the '@media/width', '@media/height' and <a descriptor>aspect-ratio</a> <a>media features</a>
	should be used, rather than '@media/device-width', '@media/device-height' and
	'@media/device-aspect-ratio', which refer to the physical size of the device
	regardless of how much space is available for the document being laid out. The
	device-* <a>media features</a> are also sometimes used as a proxy to detect
	mobile devices. Instead, authors should use <a>media features</a> that better
	represent the aspect of the device that they are attempting to style against.

<h3 id="device-width" class="no-toc no-num">
device-width</h3>

	<pre class='descdef mq'>
	Name: device-width
	Value: <<length>>
	For: @media
	Type: range
	</pre>

	The '@media/device-width' media feature describes the width of the rendering surface of the output device.
	For [=continuous media=], this is the width of the <a>Web-exposed screen area</a>.
	For [=paged media=], this is the width of the page sheet size.

	'@media/device-width' is <a>false in the negative range</a>.

	<div class="example">
		<pre>@media (device-width < 800px) { … }</pre>

		In the example above, the style sheet will apply only to screens
		less than ''800px'' in length.
		The ''px'' unit is of the logical kind,
		as described in the <a href="#units">Units</a> section.
	</div>

	Note: If a device can be used in multiple orientations,
	such as portrait and landscape,
	the 'device-*' media features reflect the current orientation.

<h3 id="device-height" class="no-toc no-num">
device-height</h3>

	<pre class='descdef mq'>
	Name: device-height
	Value: <<length>>
	For: @media
	Type: range
	</pre>

	The '@media/device-height' media feature describes the height of the rendering surface of the output device.
	For [=continuous media=], this is the height of the <a>Web-exposed screen area</a>.
	For [=paged media=], this is the height of the page sheet size.

	'@media/device-height' is <a>false in the negative range</a>.

	<div class="example">
		<pre>&lt;link rel="stylesheet" media="(device-height > 600px)" /&gt;</pre>

		In the example above, the style sheet will apply only to screens
		taller than 600 vertical pixels.
		Note that the definition of the ''px'' unit is the same as in other parts of CSS.
	</div>


<h3 id='device-aspect-ratio' class="no-toc no-num">
device-aspect-ratio</h3>

	<pre class='descdef mq'>
	Name: device-aspect-ratio
	Value: <<ratio>>
	For: @media
	Type: range
	</pre>

	The '@media/device-aspect-ratio' media feature is defined as the ratio of
	the value of the '@media/device-width' media feature to
	the value of the '@media/device-height' media feature.

	<div class="example">
		For example, if a screen device with square pixels
		has 1280 horizontal pixels and 720 vertical pixels
		(commonly referred to as “16:9”),
		the following media queries will all match the device:

		<pre>
		@media (device-aspect-ratio: 16/9) { … }
		@media (device-aspect-ratio: 32/18) { … }
		@media (device-aspect-ratio: 1280/720) { … }
		@media (device-aspect-ratio: 2560/1440) { … }
		</pre>
	</div>

	<wpt>
		device-aspect-ratio-002.html
		device-aspect-ratio-003.html
		device-aspect-ratio-004.html
		device-aspect-ratio-006.html
	</wpt>

<h2 id="changes" class="no-num">
Changes</h2>

	<em>This section is not normative.</em>

<div class="non-normative">

<h3 id="changes-since-2021-12-12">
Changes Since the 18 December 2021 Working Draft</h3>

In addition to editorial changes and minor clarifications,
the following changes and additions were made to this module since the
<a href="https://www.w3.org/TR/2021/WD-mediaqueries-5-20211218/">2021-12-18 Working Draft</a>:

* Moved 'display mode' definition back to [[APPMANIFEST]] ('@media/display-mode' media feature remains
	here). (See <a href="https://github.com/w3c/csswg-drafts/issues/7306">Issue 7306</a>)
* Establish a normative reference for [[Display-P3]]
* Disallow use of ''layer'' as a media type, rather than merely treat it as an unknown one, for compatibility with [=cascade layers=].
* Clarify intent of '@media/prefers-reduced-motion'
* Added further discussion of fingerprinting vectors

<h3 id="changes-since-2020-07-31"
oldids="video-width, descdef-media-video-width, video-height, descdef-media-video-height, video-resolution, descdef-media-video-resolution">
Changes Since the 2020-07-31 Working Draft</h3>

In addition to editorial changes and minor clarifications,
the following changes and additions were made to this module since the
<a href="https://www.w3.org/TR/2020/WD-mediaqueries-5-20200731/">2020-07-31 Working Draft</a>:

	* Adopted 'display mode' definition and media feature from [[APPMANIFEST]].
		(See <a href="https://github.com/w3c/csswg-drafts/issues/6343">Issue 6343</a>)
	* Dropped the media features what were meant to query about the geometry of the video plane
		in <a href="#video-prefixed-features">bi-plane implementations</a>:
		<code>video-width</code>,
		<code>video-height</code>,
		and <code>video-resolution</code>.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/5044">Issue 5044</a>)
	* Renamed '@media/prefers-contrast' values <code>high</code> and <code>low</code>
		to ''prefers-contrast/more'' and ''prefers-contrast'' less.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/2942">Issue 2943</a>)
	* Rework the interaction between '@media/prefers-contrast' and '@media/forced-colors',
		retiring <code>prefers-contrast: forced</code> and introducing ''prefers-contrast/custom''.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/5433">Issue 5433</a>)
		and <a href="https://github.com/w3c/csswg-drafts/issues/6036">Issue 6036</a>)
	* Added the '@media/horizontal-viewport-segments' and '@media/vertical-viewport-segments' media feature.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/6234">Issue 6234</a>)
	* Added the '@media/nav-controls' media feature.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/6234">Issue 6234</a>)
	* Make it possible for multiple values of '@media/dynamic-range' to match at the same time.
		(See <a href="https://github.com/w3c/csswg-drafts/issues/6793">Issue 6793</a>)


<h3 id="changes-since-2020-07-15">
Changes Since the 2020-07-15 Working Draft</h3>

The following additions were made to this module since the
<a href="https://www.w3.org/TR/2020/WD-mediaqueries-5-20200715/">2020-07-15 Working Draft</a>:

<ul>
	<li>
		Added a UA style sheet rule for '@media/inverted-colors'.

	<li>
		Added the ''prefers-contrast: forced'' value.

	<li>
		Remove the <code>light-level</code> media feature
		as it is redundant with ''prefers-contrast'' and ''prefers-color-scheme'';
		add examples of how these media features may be automatically inferred by the user agent
		based on the same factors <code>light-level</code> was expected to respond to.

</ul>

<h3 id="changes-since-2020-06-03">
Changes Since the 2020-06-03 Working Draft</h3>

The following additions were made to this module since the
<a href="https://www.w3.org/TR/2020/WD-mediaqueries-5-20200603/">2020-06-03 Working Draft</a>:

<ul>
	<li>
		Merged the content of level 4 into this specification.
		It previously was maintained as a delta over level 4.

	<li>
		Made a few editorial tweaks.

</ul>

<h3 id="changes-since-2020-03-18">
Changes Since the 2020-03-18 Working Draft</h3>

The following additions were made to this module since the
<a href="https://www.w3.org/TR/2020/WD-mediaqueries-5-20200318/">2020-03-18 Working Draft</a>:

<ul>
	<li>
		Added 'video-*' and '@media/dynamic-range' media features

	<li>
		Removed 'prefers-color-scheme: no-preference'
</ul>

<h3 id="changes-since-fpwd">
Changes Since the First Public Working Draft</h3>

The following additions were made to this module since the
<a href="https://www.w3.org/TR/2020/WD-mediaqueries-5-20200303/">2020-03-03 First Public Working Draft</a>:

<ul>
	<li>
		Highlight some known issues inline in the document.
</ul>

<h3 id="changes-for-fpwd">
Changes for FPWD (since the Media Queries Level 4)</h3>

The following additions were made to create the First Public Working Draft of this module, since the
<a href="https://www.w3.org/TR/mediaqueries-4/">Media Queries Level 4</a>:

<ul>
	<li>
		Reinstate the <code>light-level</code>, '@media/inverted-colors', and Custom Media Queries sections
		from earlier Media Queries Level 4 drafts.

	<li>
		Added '@media/prefers-reduced-motion',
		'@media/prefers-reduced-transparency',
		'@media/prefers-contrast',
		'@media/prefers-color-scheme',
		and '@media/forced-colors' media features.
</ul>

<h2 class="no-num" id="acknowledgments">
Acknowledgments</h2>

	<em>This section is not normative.</em>

This specification is the product of the W3C Working Group on
Cascading Style Sheets.

Comments from
Adam Argyle,
Amelia Bellamy-Royds,
Andreas Lind,
Andres Galante,
Arve Bersvendsen,
Björn Höhrmann,
Chen Hui Jing,
Chris Lilley,
Chris Rebert,
Christian Biesinger,
Christoph Päper,
Elika J. Etemad (fantasai),
Emilio Cobos Álvarez,
François Remy,
Frédéric Wang,
Fuqiao Xue,
Greg Whitworth,
Ian Pouncey,
James Craig,
Jay Harris,
Jinfeng Ma,
Kivi Shapiro,
L. David Baron,
Masataka Yakura,
Matt Giuca,
Melinda Grant,
Michael Smith,
Nicholas C. Zakas
Patrick H. Lauke,
Philipp Hoschka,
Rick Byers,
Rijk van Geijtenbeek,
Rik Cabanier,
Roger Gimson,
Rossen Atanassov,
Sam Sneddon,
Sigurd Lerstad,
Simon Kissane,
Simon Pieters,
Stephen Chenney,
Steven Pemberton,
Susan Lesch,
Tantek Çelik,
Thomas Wisniewski,
Vi Nguyen,
Xidorn Quan,
Yves Lafon,
akklesed,
and 張俊芝
improved this specification.

<h2 class=no-num id=privacy>Privacy Considerations</h2>

	<em>This section is not normative.</em>

<div class="non-normative">

	Issue: this section is <a href="https://github.com/w3c/csswg-drafts/issues?q=is%3Aopen+is%3Aissue+label%3Amediaqueries-5+label%3Aprivacy-tracker">incomplete</a>

	Many media features enable fingerprinting of users
	based on the display and interaction characteristics of their device:

	* <a href="#mf-colors">Colors</a>: '@media/color', '@media/color-index', '@media/monochrome', '@media/color-gamut' and '@media/dynamic-range'
	* <a href="#mf-viewport-characteristics">Viewport characteristics</a>: '@media/aspect-ratio', '@media/orientation',
		'@media/horizontal-viewport-segments' and
		'@media/vertical-viewport-segments'
	* <a href="#mf-display-quality">Display quality</a>: '@media/resolution', '@media/scan', '@media/grid', '@media/update' and '@media/environment-blending'
	* <a href="#mf-interaction">Interaction devices</a>: '@media/pointer', '@media/hover', '@media/any-pointer' and '@media/any-hover'.

	The '@media/environment-blending' feature is of particular concern
	because it suggests <em>where</em> a user may be located,
	and is likely present in a small set of devices.
	Uncommon device properties are stronger fingerprinting features
	because they help segment devices into smaller sets.

	Media features that reflect operating system preferences are a fingerprinting risk
	because such preferences are correlated with characteristics of the user themselves:

	* The '@media/prefers-reduced-data' media feature may be correlated with low income and limited data.
	* The '@media/prefers-reduced-motion', '@media/prefers-color-scheme', '@media/prefers-reduced-transparency',
		'@media/forced-colors' and '@media/inverted-colors' queries reflect affordances for a range of special needs.

	Properties dependent on one of the above media queries may be accessed by script:

	* Colors and other property values may be directly accessed through computed style,
		though user agents may elect to return constants for some colors
		(see, for example, <a href="https://drafts.csswg.org/css-color-4/#css-system-colors">CSS Color 4</a>).
	* Layout affecting properties (such as font size) influence lengths, positions and sizes available to script.

	User agents may disable these media features when users have expressed sensitivity to tracking.
	Alternatively, user agents may limit the combination of features within a single page
	to reduce the fingerprinting power of the page.

	The {{PreferenceManager}} object allows querying some user-preference [=media features=]. This
	is not a privacy leak, as that information is already trivially
	available by using [=media features=] themselves.

	The {{PreferenceManager}} object also allows overriding these user-preference [=media features=]; this
	is also neither a privacy nor accessibility regression, as the [=media features=] were already ignorable by simply
	not querying them.

</div>

<h2 class=no-num id=security>Security Considerations</h2>

	<em>This section is not normative.</em>

<div class="non-normative">

	Issue: this section is <a href="https://github.com/w3c/csswg-drafts/issues?q=is%3Aopen+is%3Aissue+label%3Amediaqueries-5+label%3Asecurity-tracker+">incomplete</a>

	The '@media/display-mode' media feature allows an origin
	access to aspects of a user’s local computing environment and,
	particularly when used together with an [=application manifest=] [=manifest/display=] member [[APPMANIFEST]],
	allows an origin some measure of control over a user agent’s native UI.
	Through a CSS media query, a script can know the display mode of a web application.
	An attacker could, in such a case,
	exploit the fact that an application is being displayed in fullscreen
	to mimic the user interface of another application.

</div>
